Thousands of intersections

Thousands of intersections

Rob_Durham
Enthusiast Enthusiast
4,825 Views
64 Replies
Message 1 of 65

Thousands of intersections

Rob_Durham
Enthusiast
Enthusiast

Hi,

 

I am trying to get AutoCAD to draw a great many circles of differing radii with the centre point of the circles at a common foci point along the semi-major axis of an ellipse. The radius of all the circles are such that they will intersect the ellipse at some point.

 

The XYZ coordinates of these intersections are ultimately what I want to extract using AutoCADs data extraction utility.

 

I have successfully used Lee Macs intersections Lisp routine to draw ‘points’ at these intersections however it doesn’t like it when I have thousands of circles….it just crashes.

 

;; Intersections in Set  -  Lee Mac
;; Returns a list of all points of intersection between all objects in a supplied selection set.
;; sel - [sel] Selection Set

(defun LM:intersectionsinset ( sel / id1 id2 ob1 ob2 rtn )
    (repeat (setq id1 (sslength sel))
        (setq ob1 (vlax-ename->vla-object (ssname sel (setq id1 (1- id1)))))
        (repeat (setq id2 id1)
            (setq ob2 (vlax-ename->vla-object (ssname sel (setq id2 (1- id2))))
                  rtn (cons (LM:intersections ob1 ob2 acextendnone) rtn)
            )
        )
    )
    (apply 'append (reverse rtn))
)

(defun LM:intersections ( ob1 ob2 mod / lst rtn )
    (if (and (vlax-method-applicable-p ob1 'intersectwith)
             (vlax-method-applicable-p ob2 'intersectwith)
             (setq lst (vlax-invoke ob1 'intersectwith ob2 mod))
        )
        (repeat (/ (length lst) 3)
            (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
                  lst (cdddr lst)
            )
        )
    )
    (reverse rtn)
)

(defun c:interset ( / sel )
    (if (setq sel (ssget))
        (foreach pnt (LM:intersectionsinset sel)
            (entmake (list '(0 . "POINT") (cons 10 pnt)))
        )
    )
    (princ)
)
(vl-load-com) (princ)

 

 

Since I don’t ultimately need the circles (only the intersection points they make with the ellipse) I thought I would try using the lisp below to delete the last circle drawn (actually the second to last entity after the ‘point’) which seems to work if I run it manually. This way, the first lisp routine only needs to find one intersection each time.

 

 

(defun countback(steps / ms)
(vl-load-com)
(setq ms (vla-get-modelspace (vla-get-activedocument
(vlax-get-acad-object))))
(vlax-vla-object->ename (vla-item ms (- (vla-get-count ms) steps)))
)
 (command ".erase" (countback 2) "")
(princ)

 

 

The trouble is I am using a copy paste method from excel to the command line to draw the circles. I thought I would try and also call the above routines from the spreadsheet but I can’t seem to get it to work, it will draw the points at the intersections but then won’t delete the last circle drawn.

 

Capture.JPG

 

Since I’m no expert in Lisp and I found both of these routines on the web, can someone possibly a) help me combine them into 1 lisp adding the erase command to delete the 2nd to last entity (countback 2) or b) suggest a better way of doing this whole process?

 

Thanks in advance

 

Rob

0 Likes
Accepted solutions (1)
4,826 Views
64 Replies
Replies (64)
Message 61 of 65

Rob_Durham
Enthusiast
Enthusiast

Same way, sorry I'll give it a try once the current batch has finished.

 

Not sure if it's possible but I know you can draw a large number of circles fairly quickly. If the circles are all there to begin with, is it possible to cycle through each one and find the intersection with the ellipse without detecting circle/circle intersections?

 

Just a thought!

0 Likes
Message 62 of 65

Anonymous
Not applicable

Yes, but try the new code first. It will be faster than if we did it that way.

0 Likes
Message 63 of 65

Kent1Cooper
Consultant
Consultant

@Rob_Durham wrote:

....

It is my understanding (rightly or wrongly) that, geometrically, the ellipse and the Pellipse are the same however they are rendered on screen differently.

....

I assume the code will need to change to reflect this?


Wrongly, I'm afraid.  A PELLIPSE=1 Polyline "Ellipse" is made of 16 arc segments [draw one, pick it and look at the grips, and you'll see].  That means that within each of those stretches, it's of constant  radius, whereas a true Ellipse is of constantly-changing  radius, and can't be precisely represented by arcs [or Polyline arc segments], even if you approximated it with more  than AutoCAD's 16 [more could get closer, but there doesn't even seem to be any option to set it to a higher number].  It's pretty close to a true elliptical shape, but not close enough for your purposes, since in some areas it will throw off your position by hours.  The area I made an image of is about the worst  amount of divergence -- draw a "matching pair" as I did, ZOOM in close around that 24-or-so-degrees-off-perihelion vicinity, REGEN to make sure the curvature is corrected for the Zoom level, then PAN along it and you'll see how they get closer to each other in either direction from there.

 

Using a true Ellipse should not  require any changes in the code -- the IntersectWith method works with an Ellipse as well as with a Polyline.

Kent Cooper, AIA
Message 64 of 65

Rob_Durham
Enthusiast
Enthusiast

Then I stand corrected and will definitely be using an ellipse. Thank you.

0 Likes
Message 65 of 65

john.uhden
Mentor
Mentor

Based on @Kent1Cooper's suggestion, this might help.

It returns a list of all 525K points evenly spaced around the perimeter of a true ellipse.

It takes one argument, being the ellipse vla-object.

Actually, it returns 524521 points or one more than the number of increments, in about 6 seconds on my old laptop.

They are 3D points, but if you want to remove the Z values, that's next to nothing to do.

If your ellipse is slightly more eccentric on one side/end than the other, then you could break it into two halves and process them separately but combine the two lists into one.

 

(defun PEllipse (obj / n end inc param p pts)
  (setq n (* 364.25 24 60)
        end (vlax-curve-getendparam obj)
        inc (/ end n)
        param 0.0
  )
  (while (< param end)
    (setq p (vlax-curve-getpointatparam obj param)
          pts (cons p pts)
          param (+ param inc)
    )
  )
  (reverse pts)
)

John F. Uhden

0 Likes