How to get the coordinates of crossing lines.

How to get the coordinates of crossing lines.

Anonymous
Not applicable
4,152 Views
14 Replies
Message 1 of 15

How to get the coordinates of crossing lines.

Anonymous
Not applicable

Hello All,

I try to make a small lisp routine about intersections, one of the points is:

How to get the coordinates of line intersections from a selection set?

Can anyone help me with this?

Thanks in advange

André

0 Likes
Accepted solutions (3)
4,153 Views
14 Replies
Replies (14)
Message 2 of 15

doaiena
Collaborator
Collaborator

I think the vla-IntersectWith Method is what you are looking for.

0 Likes
Message 3 of 15

_gile
Consultant
Consultant
Accepted solution

Hi,

 

You can start from this:

;;; Returns a list of points for each intersection of the lines in the selection set
(defun getIntersections (ss / i elst lines p1 p2 intersect points)
    ;; compute a list of start and end points for each selected line
    (repeat (setq i (sslength ss))
        (setq elst  (entget (ssname ss (setq i (1- i))))
              lines (cons (list (cdr (assoc 10 elst)) (cdr (assoc 11 elst))) lines)
        )
    )
    ;; for each pair of points, search for intersections with the following pairs
    (while (cdr lines)
        (setq p1    (caar lines)
              p2    (cadar lines)
              lines (cdr lines)
        )
        (foreach l lines
            (if (setq intersect (inters p1 p2 (car l) (cadr l)))
                (setq points (cons intersect points))
            )
        )
    )
    points
)

;;; test command which draws a point on each intersection of the selected lines
(defun c:test (/ ss points)
    (if (setq ss (ssget '((0 . "LINE"))))
        (progn
            (setq points (getIntersections ss))
            (foreach p points (entmake (list (cons 0 "POINT") (cons 10 p) (cons 62 1))))
        )
    )
    (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 15

Moshe-A
Mentor
Mentor

@Anonymous  hi,

 

here is a sample program to draw red points at intersections of lines

for finding intersections between other objects it is better to move to vla-objects

 

enjoy

moshe

 

 

(defun c:test (/ ss enames^ elist0 elist1 a0 a1 b0 b1 cross)

 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (setq ss (ssget '((0 . "line"))))
  (progn
   ; create a list of enames 
   (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
    (setq enames^ (cons ename enames^)) 
   )

   (setvar "pdmode" 3)
   (setvar "pdsize" -2)

   ; outer loop, step through list chop last item
   (foreach ename0 (reverse (cdr (reverse enames^)))
(setq elist0 (entget ename0)) (setq a0 (cdr (assoc '10 elist0))) (setq a1 (cdr (assoc '11 elist0))) ; inner loop, step through list chop the first item (foreach ename1 (cdr enames^) (setq elist1 (entget ename1)) (setq b0 (cdr (assoc '10 elist1))) (setq b1 (cdr (assoc '11 elist1))) (if (setq cross (inters a0 a1 b0 b1 nil)) ; find intersection (progn (command "._point" cross) (command "._chprop" "_si" "_last" "_properties" "_color" 1 "") ) ) ); foreach ); foreach ); progn ); if (command "._undo" "_end") (setvar "cmdecho" 1) (princ) )

 

0 Likes
Message 5 of 15

_gile
Consultant
Consultant

@Moshe-A the algorithm you use may return duplicate points.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 15

Moshe-A
Mentor
Mentor

@_gile  hi,

 

Yes you are right, that's the result of desire to respond in short time.

 

thanks you

 

0 Likes
Message 7 of 15

Kent1Cooper
Consultant
Consultant

If you're talking about Line entities specifically  [not just "linework" including things like Polylines], here's another way:

(defun C:PLI ; = Points at Line Intersections
  (/ ss n lin1 m lin2 int ldata1 ldata2)
  (if (setq ss (ssget '((0 . "LINE"))))
    (repeat (1- (setq n (sslength ss)))
      (setq lin1 (ssname ss (setq n (1- n))))
      (repeat (setq m n)
        (setq lin2 (ssname ss (setq m (1- m))))
        (if
          (setq int
            (inters
              (cdr (assoc 10 (setq ldata1 (entget lin1))))
              (cdr (assoc 11 ldata1))
              (cdr (assoc 10 (setq ldata2 (entget lin2))))
              (cdr (assoc 11 ldata2))
              T ; they actually intersect
            ); inters
          ); set
          (command "_.point" "_none" int)
        ); if
      ); repeat
    ); repeat
  ); if
  (princ)
); defun

It draws the Points on the current Layer, and displays them under the current PDMODE setting -- specifics for such things could be built into it if desired.  It will draw duplicate Points only when more than two  Lines intersect at the same location.

 

Kent Cooper, AIA
0 Likes
Message 8 of 15

Kent1Cooper
Consultant
Consultant

... or, if you only want to know the locations  [looking back at the original question -- I got thrown off by other suggestions that draw Point objects], you can just change the (command)-function line in my previous Reply to this:

 

  (setq intlist (cons int intlist))

 

and the 'intlist' variable will be left containing a list of the intersection points as coordinate lists.  If that's what you need, you might also change the command name....

Kent Cooper, AIA
0 Likes
Message 9 of 15

Anonymous
Not applicable

Hello Gilles,

thanks for your reply, works great.

is it possible to give up coordinates in stead of a crossing on the screen?

Regards,

André

0 Likes
Message 10 of 15

_gile
Consultant
Consultant

@Anonymous wrote:

Hello Gilles,

thanks for your reply, works great.

is it possible to give up coordinates in stead of a crossing on the screen?

Regards,

André


Sorry I do not understand what you want, the getIntersections function in the code I posted requires a selection set of lines and returns a list of points. You can use it to suit your needs.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 11 of 15

Anonymous
Not applicable

Gilles,

0 Likes
Message 12 of 15

_gile
Consultant
Consultant
Accepted solution

You can specify the selection mode  with the ssget function: "_C" for crossing or "_W" for window.

Take care the objects have to be visible on screen to be selected. You can make a zoom using the same points before running ssget.

(command "_.zoom" "_non" pt1 "_non" pt2)
(setq ss (ssget "_W" pt1 pt2 '((0 . "LINE"))))


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 13 of 15

Anonymous
Not applicable
Accepted solution

Gilles,

Thanks, this is what I mean.

Thanks every one for help.

Regards,

André

0 Likes
Message 14 of 15

Jan_Nielsen
Observer
Observer

Hi

Can this code be rewirtten to also work with Polylines and Splines?

Regards

Jan

0 Likes
Message 15 of 15

Kent1Cooper
Consultant
Consultant

@Jan_Nielsen wrote:

Can this code be rewirtten to also work with Polylines and Splines?


It probably could be, but there are routines around already made for that.  Probably this Forum has some you can Search for, but one I'm aware of elsewhere [but have not downloaded and tried] is >here<.

Kent Cooper, AIA
0 Likes