Can you write down these two lists or are you after selecting LWpolylines & Circles to check their coordinates out?
A bit more info is needed.
Registered forum members do not see this ad.
Hi,
I want to to compare a list of LWPolyline entities with a list of Circle entities:
If the LWpolyline end point vertice XY coordinate matches a circle center coordinate XY.
Then write layer name of circle to new list.
If not Then return "no match"
I already have a subroutine which gets the (start) vertices of the LWpolyline.
Did try a repeat in a repeat...but that didn't work out.
So I am stucked here, something with mapcar lambda member?
Can somebody help me how to compare 2 lists
Greetzzz,
Gerben
Can you write down these two lists or are you after selecting LWpolylines & Circles to check their coordinates out?
A bit more info is needed.
The code below allows you to select a polyline.
It then checks if there is a circle on its END-point.
If so, it moves the circle to the layer MATCHLAYER.
Code:(defun C:CadTutor ( / polyline polylinex polyliney allcircles n ensel enlist circlex circley) (setq polyline (entget (car (entsel)))) (setq polylinex (car (cdr (assoc 10 (reverse polyline))))) (setq polyliney (car (cddr (assoc 10 (reverse polyline))))) (setq allcircles (ssget "_X" (list (cons 0 "CIRCLE")))) (setq n (sslength allcircles)) (repeat n (setq ensel (ssname allcircles (setq n (1- n)))) (setq enlist (entget ensel)) (setq circlex (car (cdr (assoc 10 enlist)))) (setq circley (car (cdr (cdr (assoc 10 enlist))))) (if (and (= polylinex circlex)(= polyliney circley)) (progn (princ "\nMatch found!") (setq enlist (subst (cons 8 "MATCHLAYER") (assoc 8 enlist) enlist)) (entmod enlist) ) (progn (princ "\nNo match...") ) ) ) (princ) )
My attempt.
Code:(defun c:Test ( / int sel ent lst ) ;; Tharwat - Date: 11.Sep.2017 ;; (if (and (or (setq int -1 sel (ssget "_X" (list '(0 . "CIRCLE") (cons 410 (getvar 'CTAB))))) (alert "Couldn't find any circle in this drawing <!>") ) (progn (while (setq ent (ssname sel (setq int (1+ int)))) (setq lst (cons (list ent (cdr (assoc 10 (entget ent)))) lst)) ) lst ) (princ "\nSelect LWpolylines to change circles reside on their end points to MatchLayer :") (setq int -1 sel (ssget '((0 . "LWPOLYLINE")))) ) (while (setq ent (ssname sel (setq int (1+ int)))) (vl-some '(lambda (p) (if (or (equal (vlax-curve-getstartpoint ent) (cadr p) 1e-4) (equal (vlax-curve-getendpoint ent) (cadr p) 1e-4) ) (entmod (append (entget (car p)) '((8 . "MatchLayer")))))) lst) ) ) (princ) ) (vl-load-com)
NOTE: if are there by any chance two circles on start & end points then just replace the function vl-some with mapcar.
Thanx man, your code work smooth, however it does not exactly what I want.
I have changed it a bit to what I want to achieve:
Changes:Code:(defun c:Test ( / int sel ent lst ) ;; Tharwat - Date: 11.Sep.2017 ;; (setq ss2_list nil) (setq wtg_id2_lst nil) (if (and (or (setq int -1 sel (ssget "_X" (list '(0 . "CIRCLE") (cons 410 (getvar 'CTAB))))) (alert "Couldn't find any circle in this drawing <!>") ) (progn (while (setq ent (ssname sel (setq int (1+ int)))) (setq ss2_list (cons (list ent (cdr (assoc 10 (entget ent)))) ss2_list)) ) ss2_list ) (princ "\nSelect LWpolylines to change circles reside on their end points to MatchLayer :") (setq int -1 sel (ssget '((0 . "LWPOLYLINE")))) ) (while (setq ent (ssname sel (setq int (1+ int)))) (vl-some '(lambda (p) (cond ((equal (vlax-curve-getendpoint ent) (cadr p) 1e-4) (setq wtg_id2_lst (cons (cdr (assoc 8 (entget (car p)))) wtg_id2_lst)) ) ((/= (vlax-curve-getendpoint ent) (cadr p) 1e-4) ; All circles are on endpoints of LWPOLYLINES ; If any circle is not on any LWPOLYLINE endpoint then break the routine with an alert ) ) ) ss2_list) ) ) (princ) ) (vl-load-com)
All circles are in separate layers
Since all circles are (or should be) on LWPOLYLINE endpoints
I want a Condition that if any LWPOLYLINE Endpoint is equal to any CIRCLE centerpoint, the Circles layer name is written to a list.
But if not equal then the routine must abort with an alert, because an x amount of circles might be moved by the CAD draftsman during modifications.
Your " WHILE VL-SOME LAMBDA IF" loop compares 1 LWPOLYLINE ENDpoint with all selected Circles center points...so correct me if I am wrong, if there are lets say 77 circles selected, 76 are not equal to the current LWPOLYLINE ENDpoint. however the other 76 Circles might match other LWPOLYLINE ENDpoints.
is this possible?
Hi Tharwat,
You code runs smooth, however this is not exactly what I want.
All Circles in my drawing are on seperate layers
Also All Circles are (or should be) located on LWPOLYLINES ENDpoints (so for now I don't need the startpoint).
If this is true then the Circles layer name must be written to a list.
But your While loop compares 1 LWpolyline Endpoint with all Circles centerpoints.
So if lets say I have 77 circles in the set, 76 of them don't match the endpoint of the current LWPOLYLINE Endpoint in the loop.
However they do match other LWPOLYLINE endpoints.
What i want to achieve is that IF any of the LWPOLYLINE Endpoints matches any of the Circles center points THEN write the Circle layer name to a list
If not then an x amount of the circles are not located on an LWPOLYLINE ENDpoint (some circles might be shifted during modifications by a CAD draftsman) the routine should abort with an alert.
I have modified your code a bit to show what I want:
Code:(defun c:Test ( / int sel ent lst ) ;; Tharwat - Date: 11.Sep.2017 ;; (setq ss2_list nil) (setq wtg_id2_lst nil) (if (and (or (setq int -1 sel (ssget "_X" (list '(0 . "CIRCLE") (cons 410 (getvar 'CTAB))))) (alert "Couldn't find any circle in this drawing <!>") ) (progn (while (setq ent (ssname sel (setq int (1+ int)))) (setq ss2_list (cons (list ent (cdr (assoc 10 (entget ent)))) ss2_list)) ) ss2_list ) (princ "\nSelect LWpolylines to change circles reside on their end points to MatchLayer :") (setq int -1 sel (ssget '((0 . "LWPOLYLINE")))) ) (while (setq ent (ssname sel (setq int (1+ int)))) (vl-some '(lambda (p) (cond ((equal (vlax-curve-getendpoint ent) (cadr p) 1e-4) (setq wtg_id2_lst (cons (cdr (assoc 8 (entget (car p)))) wtg_id2_lst)) ) ((/= (vlax-curve-getendpoint ent) (cadr p) 1e-4) ; All circles are (or should be) on endpoints of LWPOLYLINES ; So If any circle is not on any LWPOLYLINE endpoint then break the routine with an alert ) ) ) ss2_list) ) ) (princ) ) (vl-load-com)
Something like this?
Code:(defun c:Test ( / int sel ent lst fnd obj lys) ;; Tharwat - Date: 11.Sep.2017 ;; (if (and (or (setq int -1 sel (ssget "_X" (list '(0 . "CIRCLE") (cons 410 (getvar 'CTAB))))) (alert "Couldn't find any circle in this drawing <!>") ) (progn (while (setq ent (ssname sel (setq int (1+ int)))) (setq lst (cons (list ent (cdr (assoc 10 (entget ent)))) lst)) ) lst ) (princ "\nSelect LWpolylines to change circles reside on their end points to MatchLayer :") (setq int -1 sel (ssget '((0 . "LWPOLYLINE")))) ) (while (and (not fnd) (setq ent (ssname sel (setq int (1+ int))))) (if (vl-some '(lambda (o) (and (equal (vlax-curve-getendpoint ent) (cadr o) 1e-4) (setq obj o))) lst) (setq lys (cons (cdr (assoc 8 (entget (car obj)))) lys)) (progn (setq fnd t) (alert "Found a circle not reside on any end point of a LWpolyline <!>") ) ) ) ) lys ) (vl-load-com)
Wow, works like a charm! thanx
Few questions about it:
1. What does the (not fnd) and (setq fnd t) in the code? When I put a semicolon before them, I still get the same result
2. same for lst after the while statement and lys after the if statement?
Registered forum members do not see this ad.
Is it possible to catch the circle object, which not resides on any end point of LWPOLYLINE, in a variable?
Bookmarks