Jump to content

Collision Detection Code?


abraxus

Recommended Posts

I am looking for an Autocad add-on that will detect blocks that are overlapping, but I was unable to find such a thing. Has anyone here ever heard of something like that which already exists? If not, any ideas on how to write some VBA to do this?

 

The only way I can think of to write it would be to scan thru block references, comparing the size and location of each one to all the others. All the blocks would be simple rectangles. That's the easy part tho.

 

The difficult part is - I would need a function that returns true or false when passed two block references after checking to see if they overlap at all.

 

Anyone up to the challenge?

Edited by abraxus
typo
Link to comment
Share on other sites

In your sub-function / Method, extract the outer boundary coordinates of each BlockReference parameter, and iterate each coordinate to see if it resides within or without the other's coordinates (and the implicit lines that connect them), if either does so, return true, else return false.

 

Depending on the coordinate system you work in, BoundingBox may not cut it, and you may need to dig through all nested entities within each BlockReference to extract all outer most coordinates from InsertionPoint (if Insertionpoint is not also one of the outer most points, that is).

 

... Hope this helps with your coding. :beer:

Link to comment
Share on other sites

well that's basically what I was thinking, I'm just having a difficult time visualizing what the code would look like... maybe i'm making this more complex than it really is

Link to comment
Share on other sites

well that's basically what I was thinking, I'm just having a difficult time visualizing what the code would look like... maybe i'm making this more complex than it really is

 

Perhaps... But even I suffer from doing that. It's part of the process, albeit a part I wish I could avoid more often than not, but still. No biggie (unless you're under a deadline! LoL).

 

Why don't you post the code you've got so far?

 

... I jumped from Visual LISP to .NET API (skipping VBA), but I should be able to read enough, or offer some .NET code samples to try and help, until one of the VBA gurus comes along.

 

Cheers

Link to comment
Share on other sites

a bounding box wont work, because the blocks could be inserted at say a 45 degree angle... a bounding box would give a false positive of a collision

 

i do know some .NET myself, but have never used it with Autocad, just as a web development creating ASP pages for a database interface

 

for the most part, it's all just basic programming structure tho, so if you have any .NET examples that might help me too

Edited by abraxus
Link to comment
Share on other sites

I have made some progress with the code and I seem to have found a glitch with Autocad's IntersectWith method.

 

Using the code example Autodesk provides for IntersectWith (which works just fine in most cases) I have slightly modified it for testing purposes.

 

The glitch occurs only when the selected items are blocks, and at least one of the blocks is rotated at an odd angle. It comes close to the correct intersection points, but as you can see from my attached dwg file, it's not exact. It works just fine if the selected items are polylines instead of blocks (also shown in the test drawing)

 

My question is - Is this a known glitch? Is there a way to report it to Autodesk? Is there a way to compensate for the glitch to make the points exact?

 

In order to see the issue, open the dwg and delete all the lines that point to the items being compared, then run the code, and select the two items yourself and step thru the code if needed.

 

Here is the code

 

Sub Example_IntersectWith()
 Dim ptZero(2) As Double
 Dim ptLoc(2) As Double
 Dim f1 As AcadEntity
 Dim f2 As AcadEntity
 Dim basePnt As Variant
 Dim i As Integer
 Dim j As Integer
 Dim intPoints As Variant
   
 ' prompt the user to select the objects to compare
 ThisDrawing.Utility.GetEntity f1, basePnt, "Select an object"
 ThisDrawing.Utility.GetEntity f2, basePnt, "Select an object"
 
 ' Find the intersection points between the selected objects
 intPoints = f1.IntersectWith(f2, acExtendNone)
 
 If VarType(intPoints) <> vbEmpty Then
     For i = LBound(intPoints) To UBound(intPoints)
         ' draw a line from 0,0 to each point in the list
         ptLoc(0) = intPoints(j)
         ptLoc(1) = intPoints(j + 1)
         ptLoc(2) = intPoints(j + 2)
         ThisDrawing.ModelSpace.AddLine ptZero, ptLoc
         i = i + 2
         j = j + 3
     Next
 End If
End Sub

collision-test2.dwg

Link to comment
Share on other sites

Apparently the IntersectWith function, when used with BlockRefs, only considers the Bounding Box of the reference, not the individual entities that make up the Block.

 

If the routine requires BlockRef compatibility the Refs may need to be Exploded and a double For Each loop used to compare all geometry in one to all geometry in the other. And, unfortunately, BlockRefs may include other BlockRefs at multiple nested levels. It could get quite complex.:ouch:

Link to comment
Share on other sites

Thanks for the reply - explode the block - why did i not think of that approach? - but that WOULD solve the problem, however, i do need the original block to remain intact afterwards, as it is tied to an external database reference

 

as for nested blocks, i am 100% sure that will not be an issue with what i need, as the blocks are very simple blocks with no nested blocks

 

i wonder if i can explode it, process what i need to process, and then "undo" the exploding? but now i'm thinking that is not the best approach, as the block is defined as 4 separate lines, not a single polyline

 

now that you have me thinking, maybe i could parse the block reference to get the endpoints and then create a polyline for it, using that for the IntersectWith method, since the blocks are always the same block type (different scale values) and are comprised of nothing but 4 lines in a rectangular format

 

i am considering all approaches, as i need the absolute fastest way to do this... because of the very large amount of blocks i will be processing

 

i am not looking for a solution that works in every single possible case of any type of block, just this specific block would be all that i would have to get working

Edited by abraxus
added more information/typo
Link to comment
Share on other sites

still thinking...

 

i should be able to create an "in memory only" polyline entity based on the size/scale of the 4 lines in the block reference without actually drawing it in the drawing, right? then pass that "in memory only" polyline to a function for processing the intersection instead of passing it the block reference - the reason i dont want to add it to the drawing is because doing that would take more time to process within the iteration - i have thousands of blocks to process for each of thousands of drawings

 

sorry if my multiple posts are annoying anyone... i guess i am using this topic to help me keep track of my thought process for later reference, and to help out anyone else who might be interested in doing something similar - this website usually comes up first anytime i google something about "autocad vba" so it has been a great resource for me

 

SEANT, if you could throw together a function for me that would process a "fixture_block" block reference in my attached DWG (collision-test2.dwg‎) and return a AcadPolyline object which doesnt actually exist in the main DWG, I would be forever grateful - but if you are busy, I suppose I will just have to research how to do that myself.

 

again, thanks for your help getting me to "think outside of the box" (pardon the pun)

Edited by abraxus
Link to comment
Share on other sites

If I’m not mistaken, the VBA Explode method does not actually alter the entity upon which it was called. The method just returns an array of entities that are similar to the entities that made up the reference.

 

It has been a while since I’ve programmed with VBA, I believe the array of objects would have the same rotation and scale as the original BlockRef – though I’m not sure if it compensates for a non-uniform scale.

 

VBA does not offer the ability of creating entities without adding them to a database. Typically, the entities are just deleted after use.

 

If the blocks are always just rectangles – and processing speed was critical – I’d be tempted to process the entities mathematically. Certainly this entails other complexities but it may eliminate numerous database operations that incur a heavy processing time penalty.

 

I’ll ponder that, and post back if I come up with anything.

Link to comment
Share on other sites

you are right on track, SEANT - you understand exactly what i'm asking, and i understand your answer, and very much appreciate your input

 

so what you are saying is that given a selected "fixture_block" block reference, i should at least be able to process the block for the endpoints of each of the lines, store them into a memory array, and then get the coords?

 

thank you again - you are helping me solve this complex issue - thank god we are dealing with such a simple block definition which is merely a 1" by 1" square, inserted using the scaleX and scaleY for size definition

Link to comment
Share on other sites

I am interested in this also to complete a moving object clash test, An old fashioned way with lisp was to use "Inters" function it just used 4 points not actual lines etc this way like you say your doing a mathematical method not creating objects. There should be a intersect with method using only points.

 

(inters pt1 pt2 pt3 pt4) would return true or false for two imaginary lines.

 

As your using a block you could add a external definition file of the outer boundary points making the block shape this way you could add more blocks and shapes but have only 1 routine and its easier to add more shapes to a external file than adding to say a hardcoded lisp or VBA etc. The rotated blocks would need a bit more to re-calc the new co-ords.

 

Found this http://docs.autodesk.com/ACD/2013/ENU/index.html?url=files/GUID-A181D474-F817-4550-86E9-87649262FA8A.htm,topicNumber=d30e620107

Edited by BIGAL
Link to comment
Share on other sites

just to let interested people know, my collision detection code is working flawlessly now

 

in fact, it's working a bit TOO well, as it's detecting collisions to the ten thousandths of an inch...

 

my company says, they dont want it to be that accurate... lol

 

so now i need to add a quick distance tolerance check so that it doesnt detect anything less than 1/4" - which should be simple enough

 

just compare each of the 4 corners of the "block" (which i converted to a polyline to get accurate collision points) to the collision point and find the smallest one - that is the overlap value

 

unless you have a better idea, seant

Link to comment
Share on other sites

Actually, that sounds really good. VBA’s IntersectWith method no doubt calls the native objectARX code, so is optimized pretty well. The database operations do tend to be rather heavy – conceivably you are adding Polys to the database, finding intersections, then deleting said polys – but modern processors are very fast. Your design is the most straightforward so, if it performs fast enough, I say go for it.

 

The task presents an interesting optimization question, though. Native code (C++) is quite a bit faster than VBA. But for a VBA app to use that code it incurs numerous housekeeping penalties related to database operations.

 

An alternative, which would require much more coding on your part, would be to do it mathematically. The attached spreadsheet demos the matrix formula for finding intersections based on line Endpoints. Of course, this would need to be repeated for all four lines. I have to imagine this same sequence is used in the native code method.

 

My guess: VBA with the math would be faster, but would probably not be worth the effort. That “speed versus effort” benefit depends on your company, though. If there are an insane number of inserts, and an equally insane number of times this type of process needs to be run, a little extra speed may go a long way.

IntersectingLines.zip

Link to comment
Share on other sites

if you are inferring that i learn C++.... yeah every time i try to do that i fail - i am not sure what about C++ i do not understand... much like calculus.. it's like trying to read braille to me

 

i agree that a mathematical way of doing it would be faster, but then i wouldnt be able to use the IntersectWith method as it requires entities to be passed to it - i would basically be creating my own version of the IntersectWith method, and that is just WAY over my head

 

i havent had a chance to look at your attachment yet tho

 

i did get the tolerance options working tonight tho... but i am still getting some false positives so i will have to debug that this weekend

Link to comment
Share on other sites

Actually I didn’t mean to infer anything other than congratulation for a job well done.

 

I posted the spreadsheet as an example of a starting point if you were interested in a math solution. There would still be much to do, but you may find it interesting and not nearly as incomprehensible as you first thought.

 

I don’t do much VBA coding anymore, but I still hold the language in high regard. It was my introduction to programming, via Excel. As a matter of fact I think Excel VBA is the best learning environment for programming. The data and feedback is so visual, it makes some of the concepts easier to grasp.

 

I suspect C++ is for people smarter than me, or at least have more time on their hands. C# and/or VB.NET is more my style. You, like myself, may also find the .NET languages quite a bit more accessible than C++ .

Link to comment
Share on other sites

i do have experience with C# and .NET, but only on a fairly basic level... mostly in database applications where the object do most of the hard work for you

 

and i am a very visual person, and also a math person, but some math is just beyond me - vba makes things simple to develop, and i'm considering just handing off my structural logic code to a more senior developer who can mimic the logic in objectARX, which i hear is much faster

 

but to put it into quantitative terms, i have thousands of drawings to process, each drawing has about 4000 blocks to compare to one another... and with the code as written now, each of the 4000 blocks has to be compared to about 6 other blocks in each drawing... so that means my comparison routine has to run about 24,000 calculations per drawing, and each comparison has to "draw" 2 polylines in order to do it - it takes about 6 minutes for a computer with 8 processors to scan just one drawing....

 

that's why speed is so important - if i could get that down to like 30 seconds per drawing, that would be amazing

 

still much faster than the 4 hours it takes for a human to do it all manually tho

Link to comment
Share on other sites

  • 1 year later...

I need something similar to this.

 

Need something to control my pipe network any help is appreciated.

 

 

Below is the picture of the network;

 

http://postimg.org/image/r9srjn32n/

 

 

 

The green line is my main pipe and blue ones are network pipes. The red lines are hydrant points.

 

 

 

What I want is to check whether my network drawing meet below conditions or not. And for those points which do not meet below conditions the algorithm to dye white on those network pipes.

 

The conditions are;

 

- All pipes should be connected to each other with 90 degrees (see pic below)

 

http://postimg.org/image/cs1a3ms61/

 

- Pipes should touch each other (see pic below)

 

Wrong connection: http://postimg.org/image/o67gjqrlf/

 

Correct connection:http://postimg.org/image/j9k6n52jd/

 

- All hydrants should touch on pipe (see pic below)

 

Wrong connection: http://postimg.org/image/5dhzwymx5/

 

Correct connection: http://postimg.org/image/cs7jz64kf/

 

 

 

Cheers!

Link to comment
Share on other sites

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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...