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
@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:
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))
)
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
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
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 BRAUD