TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: XXL66 on June 30, 2014, 08:00:03 AM

Title: intersect with and object overlap
Post by: XXL66 on June 30, 2014, 08:00:03 AM
hi,

I need to write a routine that detects overlapping 2D objects (whole are partly). I know there is the overkill function but i need to report the problems only and there are other conditions too like layernames f.e.
So i'd like to write my own function that suits my needs. On googling it seemed that the intersectwith function would be a good start.
Next i came across Lee Mac his site (who else..) http://www.lee-mac.com/intersectionfunctions.html
However this doesn't seem to work with overlapping entities, because there isn't a real intersection or 'onseg' parameter like when using 'inters' . Are there any other functions that could be usefull ?

ty
Title: Re: intersect with and object overlap
Post by: ribarm on June 30, 2014, 08:53:13 AM
Here are some useful links, but you'll have to work your way and make it suit your needs...

http://www.theswamp.org/index.php?topic=47297.msg523245#msg523245
Title: Re: intersect with and object overlap
Post by: Lee Mac on June 30, 2014, 12:22:25 PM
However this doesn't seem to work with overlapping entities, because there isn't a real intersection or 'onseg' parameter like when using 'inters'

Have you tried using the extend mode enums for the intersectwith method? (see the first image on my site here (http://bit.ly/1iT4dlK))
Title: Re: intersect with and object overlap
Post by: XXL66 on June 30, 2014, 01:02:55 PM
I tried that, it doesn't change the result. I will probably have to break down polylines to their primitives (arcs lines) and use inters (with fuzz) of both endpoints, and for arcs both endpoints + centerpoint.
But this might be slow for large drawings and i would prefer not to explode the polylines.
 
Edit: i don't need to break them down but for lines i could compute if the points are colinear, this can be computed for arcs also, but will have to do this in c++ i guess, however i could do some xy sorting first.
Are there no functions that return me if a point is on a (sub)segment ?


 
Title: Re: intersect with and object overlap
Post by: Lee Mac on June 30, 2014, 03:49:36 PM
Could you post an example of the intersection you are looking to detect?
Title: Re: intersect with and object overlap
Post by: XXL66 on July 01, 2014, 04:30:47 AM
Hi Lee

See the drawing attached. Notice that it needs to include plines, arcs, lines and circles. All objects are in the same plane (zero elevation).
I colored the overlapping objects in yellow.
I don't have to correct the objects, just detect. In some cases the overlap will be valid (depending on layers f.e.) but that is not important now.
I will also have to use a fuzz factor f.e. 0.001m

ty
 

Title: Re: intersect with and object overlap
Post by: XXL66 on July 01, 2014, 04:40:36 AM
vlax-curve-getClosestPointTo

wouldn't this be a possibility, measuring the distance (< 0.001) ?
Title: Re: intersect with and object overlap
Post by: Lee Mac on July 01, 2014, 01:47:58 PM
Thank you for providing the drawing - I now understand what you are trying to achieve.

As you've already suggested, you could break the comparisons down by object and test for collinearity of lines, equal arc centers/radii & test the included angles.

But the vlax-curve-getclosestpointto would probably be the easiest way to automatically handle all curve objects (lines, arcs, polylines, splines, etc). You could use vlax-curve-getparamatpoint / vlax-curve-getdistatpoint to test whether a point on one object lies on another, but this wouldn't allow a fuzz factor as can be used with the vlax-curve-getclosestpointto method.

Here is a quick draft of a possible function to test whether one entity overlaps another:

Code - Auto/Visual Lisp: [Select]
  1. (defun overlap-p ( en1 en2 fuz / cnt dis pnt )
  2.           cnt 0
  3.     )
  4.     (while
  5.         (and
  6.             (< cnt 51)
  7.             (setq pnt (vlax-curve-getpointatdist en1 (* cnt dis)))
  8.             (< (distance pnt (vlax-curve-getclosestpointto en2 pnt)) fuz)
  9.         )
  10.         (setq cnt (1+ cnt))
  11.     )
  12.     (= 51 cnt)
  13. )

Will return T if all of en1 overlaps en2, e.g.:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / e1 e2 )
  2.     (if
  3.         (and
  4.             (setq e1 (car (entsel "\nSelect 1st object: ")))
  5.             (setq e2 (car (entsel "\nSelect 1st object: ")))
  6.         )
  7.         (overlap-p e1 e2 1e-6)
  8.     )
  9. )
Title: Re: intersect with and object overlap
Post by: XXL66 on July 02, 2014, 05:11:34 AM
Many thx Lee,

It seems to work but i'm trying to understand because i'm not familiar with these VLAX functions. What does the parameter actually represent ?

It confuses me  (might also have to do with the long night, we made it to the 1/4 finals btw...) because for a line i get startparam and endparam respectively 0.0 and the lenght
For a pline 0 and 3 (seem to be vertices)
For an arc real values ?

ty


edit: this doesn't seem to work in those cases when an object is only partly overlapping at the beginning or the end of another object.

Title: Re: intersect with and object overlap
Post by: owenwengerd on July 02, 2014, 11:07:35 AM
Parameters are opaque values defined under the hood by the implementer to express a 3D curve in 1 dimension. See my QuirkyPolyline sample (http://otb.manusoft.com/2013/01/quirkypolyline-exposing-foolish-programmers.htm) for a primer.
Title: Re: intersect with and object overlap
Post by: Lee Mac on July 02, 2014, 03:45:12 PM
edit: this doesn't seem to work in those cases when an object is only partly overlapping at the beginning or the end of another object.

Yes - the current function is testing whether all 51 staggered points along the first entity are within a given tolerance to the second entity.

For testing a partial overlap you could either go the geometric route, or perhaps consider the following function which will return the proportion of the object which is overlapping, or nil if less than the given tolerance is overlapping:

Code - Auto/Visual Lisp: [Select]
  1. (defun portion-overlap ( en1 en2 fuz / cnt dis idx pnt )
  2.     (setq dis (/ (vlax-curve-getdistatparam en1 (vlax-curve-getendparam en1)) 99.0)
  3.           cnt 0
  4.     )
  5.     (repeat (setq idx 100)
  6.         (if
  7.             (<
  8.                 (distance
  9.                     (setq pnt (vlax-curve-getpointatdist en1 (* (setq idx (1- idx)) dis)))
  10.                     (vlax-curve-getclosestpointto en2 pnt)
  11.                 )
  12.                 fuz
  13.             )
  14.             (setq cnt (1+ cnt))
  15.         )
  16.     )
  17.     (if (< fuz (setq cnt (/ cnt 100.0))) cnt)
  18. )

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / e1 e2 )
  2.    (if
  3.        (and
  4.            (setq e1 (car (entsel "\nSelect 1st object: ")))
  5.            (setq e2 (car (entsel "\nSelect 1st object: ")))
  6.        )
  7.        (portion-overlap e1 e2 1e-6)
  8.    )
  9. )