Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

To Find Self Intersection of LWPOLYLINE

4 REPLIES 4
Reply
Message 1 of 5
MehtaRajesh
2776 Views, 4 Replies

To Find Self Intersection of LWPOLYLINE

Hi,

I am posting useful function to find Self Intersection for selected LWPOLYLINE.
You might be having other options, but I find this one as a quickest and Simple


(defun IsSelfIntersect (l / vcnt vcnt1 crossresult pt1 pt2 pt3 pt4)
(setq vcnt 0)
(setq crossresult F)
(repeat (1- (length l))
 (setq pt1 (nth vcnt l))
   (setq pt2 (nth (1+ vcnt) l))
   (setq vcnt1 vcnt)
 (setq isdone "T")
 (while isdone
  (if (and (nth (+ 2 vcnt) l) (nth (+ 3 vcnt) l))
  (progn
   (setq pt3 (nth (+ 2 vcnt) l))
   (setq pt4 (nth (+ 3 vcnt) l))
       (if (inters pt1 pt2 pt3 pt4)
   (progn
      (setq crossresult T)
   );progn
   );if
  );progn
  (progn
   (setq isdone nil)
  );progn
  );if
    (setq vcnt (1+ vcnt))
 );while
   (setq vcnt (1+ vcnt1)) 
);repeat
crossresult
);defun

Below Function to get the Coordinate list of LWPOLYLINE

(defun lwptslw (lst / pair rtn)
  (while (setq pair (assoc 10 lst))
    (setq rtn (cons (cdr pair) rtn)
   lst (cdr (member pair lst))
    )
  )
  (reverse rtn)
)

USAGE:
Command: (IsSelfIntersect (LWPTSLW (ENTGET (CAR (ENTSEL "\nSelect Lwpolyline to find Self Intersectioni")))))

Regards,
Rajesh

4 REPLIES 4
Message 2 of 5
Kent1Cooper
in reply to: MehtaRajesh


@MehtaRajesh wrote:

....
I am posting useful function to find Self Intersection for selected LWPOLYLINE.
You might be having other options....

 

Below Function to get the Coordinate list of LWPOLYLINE
....


The (inters) approach in yours [which considers only the straight-line directions between designated points] would miss intersecting arc segments, such as a situation like this:

 

PLSelfInt.png

 

Here's a way to test for self-intersection that will catch those.  It's worth reading other posts on this thread that it comes from, for various considerations, other attempts and their shortcomings, remaining limitations of this one, etc.

 

 

;; Function name: PSC = Polyline Self-Crossing
;; To determine whether a Polyline of any type Crosses itSelf.
;; With 3D Polylines, must have true intersection in 3D, not apparent in 2D.
;; Returns T if self-crossing, nil if not.
(defun PSC (poly / pltyp plobj plverts plints)
  (setq
    pltyp (cdr (assoc 0 (entget poly)))
    plobj (vlax-ename->vla-object poly)
    plverts (length (safearray-value (variant-value (vla-get-Coordinates plobj))))
    plints (/ (length (safearray-value (variant-value (vla-intersectwith plobj plobj acExtendNone)))) 3)
  ); end setq
  (setq plverts (/ plverts (if (= pltyp "LWPOLYLINE") 2 3)))
  (if (vlax-curve-isClosed poly)
    (< plverts plints); then - closed
    (if (equal (vlax-curve-getStartPoint poly) (vlax-curve-getEndPoint poly) 1e-8); else - open
      (<= plverts plints); then - start/end at same place
      (<= plverts (1+ plints)); else - open
    ); if
  ); if
); defun
(vl-load-com)

Usage:  (PSC PolylineEntityName)

 

And although the above doesn't use this method to get them, here's a more concise way to get the Coordinates list of LWPolyline vertices [with its entity-data list as the 'lst' argument], directly, without the need for variables or (cons) or (reverse) functions:

(defun lwpverts (lst)
  (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) lst))
)

Kent Cooper, AIA
Message 3 of 5
patrice.braud
in reply to: Kent1Cooper

 

Hello Kent

 

I am looking for a routine to detect (get them as a selection at the end of the routine)

from a classic ACAD selection of MANY 2D Plines and 2D LWPlines ?

 

Please is it possible to have this routine that will use your beautiful code ?

 

If ALL 2D Plines and 2D LWPlines have NO SelfIntersect, the current selection will be empty at the end ...

 

Regards, Patrice

 

Message 4 of 5
Kent1Cooper
in reply to: patrice.braud


patrice.braud wrote:

.... 

I am looking for a routine to detect (get them as a selection at the end of the routine)

from a classic ACAD selection of MANY 2D Plines and 2D LWPlines ?

.... 

If ALL 2D Plines and 2D LWPlines have NO SelfIntersect, the current selection will be empty at the end ...

.... 


Welcome to these Forums!  [Any relation to @braudpat?]

 

Certainly that can be done.  In barest terms, something like this [untested]:

 

(setq

  PSS (ssget '((0 . "*POLYLINE"))); Polyline Selection Set

  SIPSS (ssadd); initially empty Self-Intersecting Polyline Selection Set

); setq

(if PSS

  (repeat (setq n (sslength PSS))

    (setq PL (ssname PSS (setq n (1- n))))

    (if (PSC PL) (ssadd PL SIPSS)); if it's self-intersecting, put it into SIPSS

  ); repeat

); if

 

The SIPSS selection set should then have any self-intersecting Polylines from the selection in it, or be empty [but not nil] if none were found.

 

Or, if you want to just remove those that don't intersect themselves from the original set, rather than make a different set:

(setq PSS (ssget '((0 . "*POLYLINE")))); Polyline Selection Set

(if PSS

  (repeat (setq n (sslength PSS))

    (setq PL (ssname PSS (setq n (1- n))))

    (if (not (PSC PL)) (ssdel PL SIPSS)); if it's not self-intersecting, remove it from PSS

  ); repeat

); if

Kent Cooper, AIA
Message 5 of 5
braudpat
in reply to: Kent1Cooper

 

Hello Kent

 

1) The most important : THANKS !

 

2) You are Mr Sherlock HOLMES : of course I am "braudpat" !

 

3) SORRY I was walking through Forums with the wrong Login ...

 

Regards, Patrice

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost