### Author Topic: Fasted way to find a closed polyline by point inside  (Read 8085 times)

0 Members and 1 Guest are viewing this topic.

#### Marc'Antonio Alessi ##### Fasted way to find a closed polyline by point inside
« on: October 02, 2014, 11:28:10 AM »
maybe the solution is very simple...
As in subject: fasted way to find a closed polyline.
known data:
- internal point
- polyline layer

#### Master_Shake

• Swamp Rat
• Posts: 1447 ##### Re: Fasted way to find a closed polyline by point inside
« Reply #1 on: October 02, 2014, 12:05:17 PM »
Code - Auto/Visual Lisp: [Select]
1. (sssetfirst nil (setq a (ssget "_X" '((8 . "LAYER")(0 . "LWPOLYLINE") (70 . 1)) )))
2.

Not sure what you mean by internal point? What if you have a polyline within a polyline?

#### Marc'Antonio Alessi ##### Re: Fasted way to find a closed polyline by point inside
« Reply #2 on: October 02, 2014, 12:10:56 PM »
Not sure what you mean by internal point? What if you have a polyline within a polyline?
Normally there is not this possibility,  if there could be also the first polyline found can be good.

#### RC

• Guest ##### Re: Fasted way to find a closed polyline by point inside
« Reply #3 on: October 02, 2014, 01:52:45 PM »
do you mean something similar to the BOUNDARY command??? ##### Re: Fasted way to find a closed polyline by point inside
« Reply #4 on: October 02, 2014, 03:00:16 PM »
Hi

Just a thought:

Code - Auto/Visual Lisp: [Select]
1. (if (setq ss
2.              "_F"
3.              (list internalPoint (getvar 'extmin))
4.              (list '(0 . "lwpolyline") (cons 8 layerName) '(-4 . "&") '(70 . 1))
5.            )
6.     )
7.   (ssname ss 0)
8. )
Speaking English as a French Frog

#### ribarm ##### Re: Fasted way to find a closed polyline by point inside
« Reply #5 on: October 02, 2014, 03:03:46 PM »
Here, try this...

Code - Auto/Visual Lisp: [Select]
1. (defun selcllwbypt+lay (pt         layer      /          rlw
2.                         member-fuzz           2nd        ss
3.                         lw         lwr        lwdxf10dxf42
4.                         lwdxf10dxf42g         lwrdxf10dxf42
5.                         lwrdxf10dxf42g        i          lwe
6.                         lwd        lwdg       e          el
7.                        )
8.
9.   (defun rlw (lw / e x1 x2 x3 x4 x5 x6)
10.     ;; by ElpanovEvgeniy
11.     ;; reverse lwpolyline
12.     (if (= (cdr (assoc 0 (setq e (entget lw)))) "LWPOLYLINE")
13.         (foreach a1 e
14.           (cond ((= (car a1) 10) (setq x2 (cons a1 x2)))
15.                 ((= (car a1) 40) (setq x4 (cons (cons 41 (cdr a1)) x4)))
16.                 ((= (car a1) 41) (setq x3 (cons (cons 40 (cdr a1)) x3)))
17.                 ((= (car a1) 42)
18.                  (setq x5 (cons (cons 42 (- (cdr a1))) x5))
19.                 )
20.                 ((= (car a1) 210) (setq x6 (cons a1 x6)))
21.                 (t (setq x1 (cons a1 x1)))
22.           )
23.         )
24.             (reverse x1)
25.                   (cons
26.                     'list
27.                     (list x2
28.                           (cdr (reverse (cons (car x3) (reverse x3))))
29.                           (cdr (reverse (cons (car x4) (reverse x4))))
30.                           (cdr (reverse (cons (car x5) (reverse x5))))
31.                     )
32.                   )
33.                 )
34.               )
35.               x6
36.             )
37.           )
38.         )
39.         (entupd lw)
40.       )
41.     )
42.   )
43.
44.   (defun member-fuzz (e l f)
45.     (vl-member-if
46.         (lambda (x)
47.           (and (equal (car x) (car e) f) (equal (cadr x) (cadr e) f))
48.         )
49.       )
50.       l
51.     )
52.   )
53.
54.   (defun 2nd (lst)
55.     (if lst (cons (car lst) (2nd (cddr lst))))
56.   )
57.
58.   (setq el (entlast))
59.   (setq ss (ssget "_A"
60.                   (list '(0 . "LWPOLYLINE")
61.                         (cons 8 layer)
62.                         '(-4 . "&=")
63.                         '(70 . 1)
64.                         (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model"))
65.                   )
66.            )
67.   )
68.   (command "_.SELECT" ss "")
69.   (command "_.-BOUNDARY"     "_A"     "_B"     "_N"     "_P"
70.            ""       "_I"     "_Y"     "_O"     "_P"     "_X"
71.            pt       ""
72.           )
73.   (if (not (eq el (entlast)))
74.       (setq lw (entget (entlast)))
75.       (setq lwr (entget (rlw (entlast))))
76.       (setq lwdxf10dxf42
77.              (vl-remove-if-not
78.                (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
79.                lw
80.              )
81.       )
82.       (setq lwdxf10dxf42g
83.              (mapcar (function (lambda (a b) (list a b)))
84.                      (2nd lwdxf10dxf42)
85.                      (2nd (cdr lwdxf10dxf42))
86.              )
87.       )
88.       (setq lwrdxf10dxf42
89.              (vl-remove-if-not
90.                (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
91.                lwr
92.              )
93.       )
94.       (setq lwrdxf10dxf42g
95.              (mapcar (function (lambda (a b) (list a b)))
96.                      (2nd lwrdxf10dxf42)
97.                      (2nd (cdr lwrdxf10dxf42))
98.              )
99.       )
100.       (setq i -1)
101.       (while (and (not e) (setq lwe (ssname ss (setq i (1+ i)))))
102.         (setq lwd
103.                (vl-remove-if-not
104.                  (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
105.                  (entget lwe)
106.                )
107.         )
108.         (setq
109.           lwdg (mapcar (function (lambda (a b) (list a b)))
110.                        (2nd lwd)
111.                        (2nd (cdr lwd))
112.                )
113.         )
114.         (if
115.           (or
116.               (function (lambda (x) (member-fuzz x lwdxf10dxf42g 1e-4)))
117.               lwdg
118.             )
119.               (function (lambda (x) (member-fuzz x lwrdxf10dxf42g 1e-4)))
120.               lwdg
121.             )
122.           )
123.            (setq e lwe)
124.         )
125.       )
126.       (entdel (entlast))
127.       (if e (sssetfirst nil (ssadd e)))
128.     )
129.   )
130.   (princ)
131. )
132.
« Last Edit: October 25, 2014, 01:22:21 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)  ##### Re: Fasted way to find a closed polyline by point inside
« Reply #6 on: October 02, 2014, 03:08:55 PM »
Here's a quickly written ray-casting method, compatible with straight-segmented polylines only:

Code - Auto/Visual Lisp: [Select]
1. (defun c:test ( / e p )
2.     (if (setq p (getpoint "\nSpecify point: "))
3.         (if (setq e (polyfrominsidepoint p))
5.             (princ "\nNo polyline found.")
6.         )
7.     )
8.     (princ)
9. )
10. (defun polyfrominsidepoint ( p / e i r s )
11.     (if
12.         (setq i -1 s
13.             (ssget "_X"
14.                 (list '(0 . "LWPOLYLINE") '(-4 . "&=") '(70 . 1)
15.                     (if (= 1 (getvar 'cvport))
16.                         (cons 410 (getvar 'ctab))
17.                        '(410 . "Model")
18.                     )
19.                 )
20.             )
21.         )
22.         (while (and (null r) (setq e (ssname s (setq i (1+ i)))))
23.             (if (raycast p (mapcar 'cdr (vl-remove-if-not '(lambda ( x ) (= 10 (car x))) (entget e))))
24.                 (setq r e)
25.             )
26.         )
27.     )
28.     r
29. )
30. (defun raycast ( p l )
31.     (= 1
32.         (logand 1
33.                 (vl-remove 'nil
34.                        '(lambda ( a b ) (inters p (mapcar '+ p '(1e8 0.0)) a b))
35.                         (cons (last l) l)
36.                         l
37.                     )
38.                 )
39.             )
40.         )
41.     )
42. ) ##### Re: Fasted way to find a closed polyline by point inside
« Reply #7 on: October 03, 2014, 03:38:00 AM »
The raycasting method has a fundamental flaw:

Code - Auto/Visual Lisp: [Select]
1. ; 20140220
2. ; See: http://paulbourke.net/geometry/polygonmesh/
3. (defun KGA_Geom_PointInsidePointList_P (pt ptLst)
4.   (<
5.     pi
6.     ;; The absolute value of the total angle is 2pi for an inside point.
7.     (abs
8.         '+
9.           '(lambda (pt1 pt2)
10.             (KGA_Geom_Angle pt1 pt pt2)
11.           )
12.           ptLst
13.           (append (cdr ptLst) (list (car ptLst)))
14.         )
15.       )
16.     )
17.   )
18. )
19.
20. ; 20140220
21. ; Return value: -pi <= angle <= pi
22. (defun KGA_Geom_Angle (pt1 pt2 pt3 / ang)
23.   (cond
24.     ((<= (- pi) (setq ang (- (angle pt2 pt3) (angle pt2 pt1))) pi)
25.       ang
26.     )
27.     ((minusp ang)
28.       (+ ang pi pi)
29.     )
30.     (T
31.       (- ang pi pi)
32.     )
33.   )
34. )

#### Marc'Antonio Alessi ##### Re: Fasted way to find a closed polyline by point inside
« Reply #8 on: October 03, 2014, 08:27:47 AM »
First of all thank you all for the answers:

@gile: this is good for another case that I have to solve, but in this case it select too many objects
using: (getvar 'extmin).

roy_043: I do not have the point list to use your function I only have a point

I try Lee Mac or ribarm (more complex) suggestion.
I'll see if I have problems.

Grazie ancora.

#### Stefan

• Bull Frog
• Posts: 230 ##### Re: Fasted way to find a closed polyline by point inside
« Reply #9 on: October 03, 2014, 09:52:15 AM »
The initial selection set can be reduced using a filter on coordinates
Code - Auto/Visual Lisp: [Select]
1. (defun c:test (/ p)
2.   (if
3.     (setq p (getpoint "\nSelect point: "))
4.     (sssetfirst nil
5.       (ssget "X"
6.              (list '(0 . "LWPOLYLINE")
7.                    '(8 . "Layer");<----
8.                    '(70 . 1)
9.                    '(-4 . ">=,>=,*") (cons 10 p)
10.                    '(-4 . "<=,<=,*") (cons 10 p)
11.              )
12.       )
13.     )
14.   )
15.   (princ)
16. )

If, by any chance, there are only rectangles in WCS, this is all you need. Complex objects requires a checking routine. ##### Re: Fasted way to find a closed polyline by point inside
« Reply #10 on: October 03, 2014, 10:17:38 AM »
@gile: this is good for another case that I have to solve, but in this case it select too many objects
using: (getvar 'extmin).

(ssname ss 0)
You select only the first object (crossed by "fence")

Ciao ##### Re: Fasted way to find a closed polyline by point inside
« Reply #11 on: October 03, 2014, 10:38:28 AM »
roy_043: I do not have the point list to use your function I only have a point
My KGA_Geom_PointInsidePointList_P function is an alternative for Lee's raycast function. Both functions take a point and a point list as arguments.

#### ribarm ##### Re: Fasted way to find a closed polyline by point inside
« Reply #12 on: October 03, 2014, 10:48:11 AM »
@gile: this is good for another case that I have to solve, but in this case it select too many objects
using: (getvar 'extmin).

(ssname ss 0)
You select only the first object (crossed by "fence")

Ciao

And you have to be in visible screen while running lisp... With my function that's not important...

Ciao
Marko Ribar, d.i.a. (graduated engineer of architecture) #### Marc'Antonio Alessi ##### Re: Fasted way to find a closed polyline by point inside
« Reply #13 on: October 03, 2014, 01:08:18 PM »
roy_043: I do not have the point list to use your function I only have a point
My KGA_Geom_PointInsidePointList_P function is an alternative for Lee's raycast function. Both functions take a point and a point list as arguments.
Ok I understand, sorry for the misinterpretation and thanks again.
Ciao.

#### Marc'Antonio Alessi ##### Re: Fasted way to find a closed polyline by point inside
« Reply #14 on: October 03, 2014, 01:13:28 PM »
I think I have many options to choose from, I'll try in a real drawing to find the faster and I will tell you my opinion.
Thank you all.