# TheSwamp

## Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Marc'Antonio Alessi on October 02, 2014, 11:28:10 AM

Title: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi 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
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Master_Shake 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?
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: RC on October 02, 2014, 01:52:45 PM
do you mean something similar to the BOUNDARY command???
Title: Re: Fasted way to find a closed polyline by point inside
Post by: gile 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. )
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Lee Mac 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. )
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 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. )
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Stefan 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: GP 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
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm 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
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi 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.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 06, 2014, 10:00:00 AM
I have edited many functions to work also with "non closed" LWPOLYLINE see "(70 . 1)",
these are the results, all comments are well accepted, attach files and test DWG:

test_Stefan     > 1 error
selcllwbypt+lay > 4 errors
Code: [Select]
`    (GILE_TEST INTERNALPOINT LAYERNAME)...........1186 / 12.27 <fastest>    (TEST_STEFAN INTERNALPOINT LAYERNAME).........1373 / 10.6    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT).......5273 / 2.76    (POLYFROMINSIDEPOINT INTERNALPOINT)...........5632 / 2.58    (SELCLLWBYPT+LAY INTERNALPOINT LAYER...).....14555 / 1 <slowest>    (TEST_STEFAN INTERNALPOINT LAYERNAME)........1810 / 5.83 <fastest>    (GILE_TEST INTERNALPOINT LAYERNAME)..........2137 / 4.93    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT)......6568 / 1.61    (POLYFROMINSIDEPOINT INTERNALPOINT).........10545 / 1 <slowest>    (GILE_TEST INTERNALPOINT LAYERNAME).........1185 / 5.45 <fastest>    (TEST_STEFAN INTERNALPOINT LAYERNAME).......1373 / 4.7    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT).....6240 / 1.03    (POLYFROMINSIDEPOINT INTERNALPOINT).........6458 / 1 <slowest>`
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 on October 06, 2014, 10:51:32 AM
I don't know the context you want to use the code in, but I would not focus on speed just yet. All code examples have one or more issues:
- Bulges are not taken into account.
- Polylines may not be bisected by other polylines.
- The polyline must have an edge between the point and extmin.
- The polyline must be rectangular.
...
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm on October 06, 2014, 11:28:29 AM
I don't know the context you want to use the code in, but I would not focus on speed just yet. All code examples have one or more issues:
- Bulges are not taken into account.
- Polylines may not be bisected by other polylines.
- The polyline must have an edge between the point and extmin.
- The polyline must be rectangular.
...

All these issues are taken into consideration with my code... Maybe that's why it's the slowest... Or I missed something in OP's request?
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 06, 2014, 11:39:29 AM
I don't know the context you want to use the code in, but I would not focus on speed just yet. All code examples have one or more issues:
- Bulges are not taken into account.
- Polylines may not be bisected by other polylines.
- The polyline must have an edge between the point and extmin.
- The polyline must be rectangular.
...
All these issues are taken into consideration with my code... Maybe that's why it's the slowest... Or I missed something in OP's request?
Marko did you seen my dwg?  There are 4 errors (selcllwbypt+lay > 4 errors)...
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm on October 06, 2014, 12:22:50 PM
Marko did you seen my dwg?  There are 4 errors (selcllwbypt+lay > 4 errors)...

Yes, the problem is fuzz factor... Change 1e-10 to 1e-4 and it'll work...

[EDIT] : I've updated code in my post... Test it now... [/EDIT]
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 on October 06, 2014, 02:52:47 PM
All these issues are taken into consideration with my code... Maybe that's why it's the slowest... Or I missed something in OP's request?
I find that your code does not work if a polyline is bisected by another and if I click a point that is internal to the first and external to the second. Note: I use BricsCAD.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 06, 2014, 04:08:36 PM
Marko did you seen my dwg?  There are 4 errors (selcllwbypt+lay > 4 errors)...

Yes, the problem is fuzz factor... Change 1e-10 to 1e-4 and it'll work...

[EDIT] : I've updated code in my post... Test it now... [/EDIT]
Ok, now is ok.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 06, 2014, 04:10:34 PM
All these issues are taken into consideration with my code... Maybe that's why it's the slowest... Or I missed something in OP's request?
I find that your code does not work if a polyline is bisected by another and if I click a point that is internal to the first and external to the second. Note: I use BricsCAD.
For this i think Lee Mac and your KGA... are OK.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 06, 2014, 05:08:46 PM
I don't know the context you want to use the code in, but I would not focus on speed just yet. All code examples have one or more issues:
- Bulges are not taken into account.
- Polylines may not be bisected by other polylines.
- The polyline must have an edge between the point and extmin.
- The polyline must be rectangular.
...
Sorry for the delay but I do not see my reply (about 5 hours ago) so I rewrite it:

The contest is my sample DWG:
ok - Bulges are not taken into account.
ok - Polylines may not be bisected by other polylines.
ok - The polyline must have an edge between the point and extmin.

No - The polyline must be rectangular.
Not true but many functions works in this situation.      If there is a function that satisfies all it is better...

Thanks
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Lee Mac on October 06, 2014, 05:22:33 PM
The raycasting method has a fundamental flaw:

A messy attempt to avoid such issues:

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 (pointinsidepoly-p p (vlax-ename->vla-object e))
24.                 (setq r e)
25.             )
26.         )
27.     )
28.     r
29. )
30. (defun pointinsidepoly-p ( pnt obj )
31.     (raycast
32.             (vlax-3D-point pnt)
33.             (vlax-3D-point (mapcar '+ pnt '(1.0 0.0 0.0)))
34.         )
35.         pnt obj (groupn (vlax-get obj 'coordinates) 2)
36.     )
37. )
38. (defun raycast ( ray pnt obj vtx / lst )
39.     (if (and (setq lst (groupn (vlax-invoke ray 'intersectwith obj acextendnone) 3))
40.                '(lambda ( x )
41.                     (or (vl-some '(lambda ( y ) (equal 0.0 (distance x y) 1e-8)) vtx)
42.                         (equal 0.0
43.                             (distance '(0.0 0.0 0.0)
44.                                 (v^v (vlax-curve-getfirstderiv obj (vlax-curve-getparamatpoint obj x))
45.                                      (mapcar '- x pnt)
46.                                 )
47.                             )
48.                             1e-8
49.                         )
50.                     )
51.                 )
52.                 lst
53.             )
54.             (< (angle '(0.0 0.0 0.0) (vlax-get ray 'directionvector)) 6)
55.         )
56.             (vlax-invoke ray 'rotate pnt 0.17)
57.             (raycast ray pnt obj vtx)
58.         )
59.             (vla-delete ray)
60.             (= 1 (logand 1 (length lst)))
61.         )
62.     )
63. )
64. (defun groupn ( l n / x r )
65.     (repeat (/ (length l) n)
66.         (repeat n
67.             (setq x (cons (car l) x)
68.                   l (cdr l)
69.             )
70.         )
71.         (setq r (cons (reverse x) r)
72.               x nil
73.         )
74.     )
75.     (reverse r)
76. )
77. (defun v^v ( u v )
78.     (list
80.         (- (* (car  v) (caddr u)) (* (car  u) (caddr v)))
81.         (- (* (car  u) (cadr  v)) (* (car  v) (cadr  u)))
82.     )
83. )

Don't expect it to be fast though!
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm on October 07, 2014, 07:05:50 AM
Here is my newest version... It's much more simple than previous, and it satisfies all previously mentioned issues... And it's fast enough - for my standards...

Code - Auto/Visual Lisp: [Select]
1. (defun selcllwbypt+lay-2 (pt         layer      /          insidep
2.                           el         ss         lw         i
3.                           lwe        e
4.                          )
5.
6.
7.   ;;======================================================================;;
8.   ;;    DETERMINING IF A POINT LIES ON THE INTERIOR OF A CLOSED ENTITY      ;;
9.   ;;======================================================================;;
10.
11.   ;;  Idea was stoled from Eugeny Kalney
12.   ;;  http://www.k-prof.com.ru/
13.   ;;  written by Fatty The Old Horse
14.   ;;  9/29/05 edited: 9/30/05
15.
16.   (defun insidep (pt entn / big flag obj1 obj2 obj3 p1 p2 small)
17.     (if (and pt entn)
18.         (setq obj1 (vlax-ename->vla-object entn))
19.         (setq obj2 (car (vlax-invoke obj1 'Offset 0.001))
20.               obj3 (car (vlax-invoke obj1 'Offset -0.001))
21.         )
22.         (if (> (vla-get-area obj2) (vla-get-area obj3))
23.             (set 'big obj2)
24.             (set 'small obj3)
25.           )
26.             (set 'big obj3)
27.             (set 'small obj2)
28.           )
29.         )
30.         (setq p1 (vlax-curve-getClosestPointTo big pt)
31.               p2 (vlax-curve-getClosestPointTo small pt)
32.         )
33.         (if (> (distance pt p1) (distance pt p2))
34.           (setq flag T)
35.           (setq flag nil)
36.         )
37.         (mapcar (function (lambda (x)
38.                               (vla-delete x)
39.                             )
40.                           )
41.                 )
42.                 (list big small)
43.         )
44.       )
45.     )
46.     flag
47.   )
48.
49.   (setq el (entlast))
50.   (setq ss (ssget "_A"
51.                   (list '(0 . "LWPOLYLINE")
52.                         (cons 8 layer)
53.                         '(-4 . "&=")
54.                         '(70 . 1)
55.                         (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model"))
56.                   )
57.            )
58.   )
59.   (command "_.SELECT" ss "")
60.   (command "_.-BOUNDARY"     "_A"     "_B"     "_N"     "_P"
61.            ""       "_I"     "_N"     ""       "_O"     "_P"
62.            "_X"     pt       ""
63.           )
64.   (if (not (eq el (entlast)))
65.       (setq lw (entlast))
66.       (setq i -1)
67.       (while (and (not e) (setq lwe (ssname ss (setq i (1+ i)))))
68.         (if
69.           (and
70.             (vlax-invoke (vlax-ename->vla-object lw) 'intersectwith (vlax-ename->vla-object lwe) acextendnone)
71.             (insidep pt lwe)
72.           )
73.           (setq e lwe)
74.         )
75.       )
76.       (entdel (entlast))
77.       (if e (sssetfirst nil (ssadd e)))
78.     )
79.   )
80.   (princ)
81. )
82.

Regards, M.R.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 on October 07, 2014, 08:10:17 AM
@ ribarm:
Your new function insidep creates two offset copies for every entity in ss. This must slow things down for large selection sets. Two other problems with this function are that the offset distance is hard-coded and that offset can create more than one new entity.

Another case to consider:
Two nested polylines without intersections and a point inside the biggest poyline only...
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 07, 2014, 08:29:26 AM
Here is my newest version... It's much more simple than previous, and it satisfies all previously mentioned issues... And it's fast enough - for my standards...
...
Regards, M.R.
Tested on Bricscad V14: do not works. Later I will tet on AutoCAD.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 07, 2014, 08:33:49 AM
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!
> test_Stefan do not works (?)
Code: [Select]
`Elapsed milliseconds / relative speed for 2048 iteration(s):    (GILE_TEST INTERNALPOINT LAYERNAME)...........1638 / 19.75 <fastest>    (POLYFROMINSIDEPOINT INTERNALPOINT)...........6926 / 4.67    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT).......8580 / 3.77    (POLYFROMINSIDEPOINT2 INTERNALPOINT).........13494 / 2.4    (SELCLLWBYPT+LAY INTERNALPOINT LAYER...).....32355 / 1 <slowest>Elapsed milliseconds / relative speed for 1024 iteration(s):    (GILE_TEST INTERNALPOINT LAYERNAME).........1451 / 6.81 <fastest>    (POLYFROMINSIDEPOINT INTERNALPOINT).........5382 / 1.83    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT).....7488 / 1.32    (POLYFROMINSIDEPOINT2 INTERNALPOINT)........9875 / 1 <slowest>Elapsed milliseconds / relative speed for 2048 iteration(s):    (GILE_TEST INTERNALPOINT LAYERNAME)..........1825 / 11.39 <fastest>    (POLYFROMINSIDEPOINT INTERNALPOINT).........12137 / 1.71    (POLYFROMINSIDEPOINT_KGA INTERNALPOINT).....19641 / 1.06    (POLYFROMINSIDEPOINT2 INTERNALPOINT)........20779 / 1 <slowest>`a little bit slower.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm on October 07, 2014, 08:44:17 AM
@ ribarm:
Your new function insidep creates two offset copies for every entity in ss. This must slow things down for large selection sets. Two other problems with this function are that the offset distance is hard-coded and that offset can create more than one new entity.

Another case to consider:
Two nested polylines without intersections and a point inside the biggest poyline only...

Yes, it must slow things on large sel. set, but hard-coded offset value is small, so I don't think it may create more than 2 new lwpolylines... Look into OP's posted example *.dwg...

I've considered that case - updated code... Changed island detection to "_N" and chosen default ray casting method (+X)... Thanks for your remarks, Roy - they are wise...

M.R.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Lee Mac on October 07, 2014, 08:48:24 AM
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!

I'm not sure that the performance comparison between my later posted function and that posted earlier is meaningful since the first function I posted will return incorrect results under some conditions (arc-segmented polylines / ray tangent to edge etc.), and hence we are not comparing apples with apples.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 07, 2014, 09:10:54 AM
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!

I'm not sure that the performance comparison between my later posted function and that posted earlier is meaningful since the first function I posted will return incorrect results under some conditions (arc-segmented polylines / ray tangent to edge etc.), and hence we are not comparing apples with apples.
I agree with you, I did a new test with Briscad and thought it was interesting the comparision in the case not need the condition: "arc-segmented polylines / ray tangent to edge etc." (in my case).
Thanks again.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: ribarm on October 07, 2014, 09:21:57 AM
I have one remark ab this Gile's function :

Code: [Select]
`(defun gile ( internalPoint layerName )    (if (setq ss          (ssget            "_F"            (list internalPoint (getvar 'extmin))            (list '(0 . "lwpolyline") (cons 8 layerName) '(-4 . "&") '(70 . 1))          )        )        (sssetfirst nil (ssadd (ssname ss 0)))    )    (princ))`
Please, test it on posted DWG, and look into picture... So it's the fastest, but it's wrong...

Regards...
Title: Re: Fasted way to find a closed polyline by point inside
Post by: roy_043 on October 07, 2014, 09:40:22 AM
@ ribarm:
You are correct. But Gile's (or similar) code can be useful if you want the reduce the number of polylines to process.
Title: Re: Fasted way to find a closed polyline by point inside
Post by: Marc'Antonio Alessi on October 07, 2014, 01:49:09 PM
I have one remark ab this Gile's function :
..
Please, test it on posted DWG, and look into picture... So it's the fastest, but it's wrong...
Regards...
@ribarm "posted DWG" is it my DWG? Does not exist overlapping polylines in that drawing, only