Jump to content
Developer Wiki and Function Reference Links ×

Command that checks if 2 Objects intersect?


Recommended Posts

Is there a function that checks if two 2D Objects intersect?

 

I know there is IntersectSurface(), but that is a little cumbersome because it will automatically create an object of the intersection area. ( If there are multiple intersections it will create multiple objects which are very hard to keep track of, for example to delete them within a script.)

 

Link to comment

Thanks for the answer. In this case I would have to convert a large amount of objects into lines and then check each line with each line of every other object. I'm not an expert at programming but that sounds like it would take even longer than creating the intersection object and deleting it again. It would be great if Vectorworks could add a command that just checks for the intersection.

Link to comment
5 hours ago, FMA said:

... that sounds like it would take even longer than creating the intersection object and deleting it again. It would be great if Vectorworks could add a command that just checks for the intersection.

 

Whether you do it, or the engineers in the Mothership do it, it could potentially take a very long time to execute. For objects that have multiple intersection points, returning the answer(s) could also be quite unwieldy. Can you describe more specifically what you are trying to achieve? Some problems are much easier to solve than others. Trying to solve all possible combinations of all possible intersections is usually reason for finding a workaround or another approach.

 

All the best,

Raymond

Link to comment

Hello Raymond! What I want to do is:

I have a selection of 2D-Objects. Each Object will get a shadow-Polygone.

If these Polygons overlap they should be combined into one polygone. So I apply the AddSurface() Function to each combination of objects. To ease the process I skip Objects that have already been merged. And I believe to be able to keep track of the handle of the merged objects I have to only apply the AddSurface() Function when the objects actually intersect. This is what that part of the code looks like:

 

 

FOR iOBJ:= 1 TO totalOBJ DO 

 

    IF NOT ( shadeOBJ[iOBJ] = NIL ) THEN 
    
        FOR iOBJn:= 1 TO totalOBJ DO 
        
            IF NOT ( shadeOBJ[iOBJ] = shadeOBJ[iOBJn] ) THEN BEGIN

 

                temphandle:= IntersectSurface(shadeOBJ[iOBJ],shadeOBJ[iOBJn]);
    
                IF NOT ( temphandle = NIL ) THEN BEGIN
                
                    DelObject(temphandle);
    
                    shadeOBJ[iOBJ]:= AddSurface(shadeOBJ[iOBJ],shadeOBJ[iOBJn]);
                
                    shadeOBJ[iOBJn]:= NIL;
                
                END;
            
            END;
            
 

 

I'm not a professional programmer and there are probably much more efficient ways to do this. I guess I could separate the Objects into chunks first. 
    

Link to comment

Hello @FMA,
   It looks like you pretty much nailed it. 

 

   Two things – the first is just kibitzing. You can express your IF statements more concisely by using:
IF ( temphandle <> NIL ) THEN BEGIN


    instead of:

IF NOT ( temphandle = NIL ) THEN BEGIN

 

   OR NOT. Your code is syntactically correct and if it reads better to you, then leave it as is.

 

 

   The second – you should add a NIL test for your object in the inner loop. Change:
IF NOT ( shadeOBJ[iOBJ] = shadeOBJ[iOBJn] ) THEN BEGIN
 

   to:
IF NOT ( shadeOBJ[iOBJn] = NIL ) & NOT ( shadeOBJ[iOBJ] = shadeOBJ[iOBJn] ) THEN BEGIN

 

   The "&" symbol means "AND", so both clauses have to be TRUE to proceed. This way, you are only processing valid objects from your array.

 

   The shorter way to write it is:

IF ( shadeOBJ[iOBJn] <> NIL ) & ( shadeOBJ[iOBJ] <> shadeOBJ[iOBJn] ) THEN BEGIN

 


   I don't know how many objects you typically want to process, but I timed a sample drawing with 1000 objects. It seemed to hang, so I restarted and selected 155 objects. The script took about 20 seconds. With 320 objects selected it took about 120 seconds. With that in mind you probably want to limit the number of objects to process to <300, and run your script multiple times on smaller selections. Actual times may vary.


Nicely done,
Raymond

 

Link to comment

Hello Raymond. Thank you very much for your reply, I really appreciate it!

I will implement the changes you proposed, and maybe I'll find an intelligent way of sorting the input objects before I run the algorhythm in the future.

Kind Regards.

Link to comment

One possibility that I have thought of in the past but never implemented is a bounding box check.

 

Create an array that contains the handle to the objects and the bounding box coordinates of the object.

Sort the array by the Left Coordinate.

Take the Right coordinate of the first object and compare that to the left coordinate of the other objects. As soon as you hit the first object that does not overlap you don't have to test the others.

 

Repeat the above sorting the array by the top coordinate and compare the top coordinates to the bottom coordinate of the first object.

 

You will have to come up with some way to "mark" the objects that overlap so you can go back and check for actual overlap using your & Raymonds method after you have reduced the number of combinations.  Thinking about it now, I would probably use a structure for the array containing the object handle, the four bounding box points, and a DynArray of Handles to store all of the objects that overlap bounding boxes. On the first bounding box comparison run you would only store the object that overlap. Then when you do the second comparison you would only have to check the objects you already know overlap horizontally to see if they also overlap vertically.

 

I can probably explain more if you need more help.

 

And welcome to The Club.  The scriptures here are pretty generous, especially with people who are trying to learn instead of just asking for a freebie.

  • Like 1
Link to comment

@FMA,

   Like Pat, I, too, have often wondered if a BBox check would speed up processing for doing massive AddSurface operations, and like Pat, I never pursued it. After I posted last night I started to look at doing just that, but sleep happened before success and sleep won out.

 

   Today, I can confirm that testing bounding boxes for potential overlap is MUCH faster than using IntersectSurface() for the same evaluation. I ran a collection of 968 objects in a few seconds as compared to "hours?" as I presumed previously. And, I would post an example now, but my data hard drive died this afternoon. So until I get a new hard drive and restore the contents of my old one I'm going dark for a while. If you get a solution before then, post back. If not, maybe I can help you later.

 

Raymond

  • Like 1
Link to comment

@Pat Stanford I never implemented a structure into my code, but atleast the first half of your suggestion I understand and it appears to be quite feasable. I'm working on a different project now, but I will soon come back to this and if I find a good system I will post it here. And @MullinRJ I am sorry to hear that, I hope that didn't happen because of overloading your machine with VS Functions, I also experienced an increased amount of crashes lately and I get a feeling they correlate with running giant loops in vectorworks. Anyway I hope you can retrieve it and I should also backup my scripts it appears.

Link to comment
2 hours ago, FMA said:

I hope that didn't happen because of overloading your machine with VS Functions

 

😁 Good morning, @FMA. No, if that were the case it would have died from self inflicted abuse on my part years ago. 

 

   As to your more frequent crashing, it can be caused by developing scripts. Restarting VW should clear most of your issues, as long as your code is eventually running smoothly, bu it would never hurt to restart your computer once and a while in the middle of doing a lot of development work. My experience is that excessive crashing goes away once I get my scripts running smoothly. YES – BACKUP OFTEN, especially when you are scripting. I will say one thing, if you lose a script because you crashed and it's not backed up, it's amazing how fast you can recreate it from memory versus create it from scratch. Been there, done that.

 

Raymond

Edited by MullinRJ
Link to comment
14 hours ago, FMA said:

I don't use backups because I know rewriting all the code will only help me!

 

That's all well and good, but wait until you start writing longer scripts. Someday you'll want to look one up rather that recreate it.

 

Either way, have fun. That's what It's all about.

Raymond

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...