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

0 Members and 1 Guest are viewing this topic.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
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

ChrisCarlson

  • Guest
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

  • Swamp Rat
  • Posts: 1452
  • Marco
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???

gile

  • Gator
  • Posts: 2507
  • Marseille, France
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.            (ssget
  3.              "_F"
  4.              (list internalPoint (getvar 'extmin))
  5.              (list '(0 . "lwpolyline") (cons 8 layerName) '(-4 . "&") '(70 . 1))
  6.            )
  7.     )
  8.   (ssname ss 0)
  9. )
Speaking English as a French Frog

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
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.       (progn
  14.         (foreach a1 e
  15.           (cond ((= (car a1) 10) (setq x2 (cons a1 x2)))
  16.                 ((= (car a1) 40) (setq x4 (cons (cons 41 (cdr a1)) x4)))
  17.                 ((= (car a1) 41) (setq x3 (cons (cons 40 (cdr a1)) x3)))
  18.                 ((= (car a1) 42)
  19.                  (setq x5 (cons (cons 42 (- (cdr a1))) x5))
  20.                 )
  21.                 ((= (car a1) 210) (setq x6 (cons a1 x6)))
  22.                 (t (setq x1 (cons a1 x1)))
  23.           )
  24.         )
  25.         (entmod
  26.           (append
  27.             (reverse x1)
  28.             (append
  29.               (apply
  30.                 (function append)
  31.                 (apply
  32.                   (function mapcar)
  33.                   (cons
  34.                     'list
  35.                     (list x2
  36.                           (cdr (reverse (cons (car x3) (reverse x3))))
  37.                           (cdr (reverse (cons (car x4) (reverse x4))))
  38.                           (cdr (reverse (cons (car x5) (reverse x5))))
  39.                     )
  40.                   )
  41.                 )
  42.               )
  43.               x6
  44.             )
  45.           )
  46.         )
  47.         (entupd lw)
  48.       )
  49.     )
  50.   )
  51.  
  52.   (defun member-fuzz (e l f)
  53.     (vl-member-if
  54.       (function
  55.         (lambda (x)
  56.           (and (equal (car x) (car e) f) (equal (cadr x) (cadr e) f))
  57.         )
  58.       )
  59.       l
  60.     )
  61.   )
  62.  
  63.   (defun 2nd (lst)
  64.     (if lst (cons (car lst) (2nd (cddr lst))))
  65.   )
  66.  
  67.   (setq el (entlast))
  68.   (setq ss (ssget "_A"
  69.                   (list '(0 . "LWPOLYLINE")
  70.                         (cons 8 layer)
  71.                         '(-4 . "&=")
  72.                         '(70 . 1)
  73.                         (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model"))
  74.                   )
  75.            )
  76.   )
  77.   (command "_.SELECT" ss "")
  78.   (command "_.-BOUNDARY"     "_A"     "_B"     "_N"     "_P"
  79.            ""       "_I"     "_Y"     "_O"     "_P"     "_X"
  80.            pt       ""
  81.           )
  82.   (if (not (eq el (entlast)))
  83.     (progn
  84.       (setq lw (entget (entlast)))
  85.       (setq lwr (entget (rlw (entlast))))
  86.       (setq lwdxf10dxf42
  87.              (vl-remove-if-not
  88.                (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
  89.                lw
  90.              )
  91.       )
  92.       (setq lwdxf10dxf42g
  93.              (mapcar (function (lambda (a b) (list a b)))
  94.                      (2nd lwdxf10dxf42)
  95.                      (2nd (cdr lwdxf10dxf42))
  96.              )
  97.       )
  98.       (setq lwrdxf10dxf42
  99.              (vl-remove-if-not
  100.                (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
  101.                lwr
  102.              )
  103.       )
  104.       (setq lwrdxf10dxf42g
  105.              (mapcar (function (lambda (a b) (list a b)))
  106.                      (2nd lwrdxf10dxf42)
  107.                      (2nd (cdr lwrdxf10dxf42))
  108.              )
  109.       )
  110.       (setq i -1)
  111.       (while (and (not e) (setq lwe (ssname ss (setq i (1+ i)))))
  112.         (setq lwd
  113.                (vl-remove-if-not
  114.                  (function (lambda (x) (or (eq (car x) 10) (eq (car x) 42))))
  115.                  (entget lwe)
  116.                )
  117.         )
  118.         (setq
  119.           lwdg (mapcar (function (lambda (a b) (list a b)))
  120.                        (2nd lwd)
  121.                        (2nd (cdr lwd))
  122.                )
  123.         )
  124.         (if
  125.           (or
  126.             (vl-every
  127.               (function (lambda (x) (member-fuzz x lwdxf10dxf42g 1e-4)))
  128.               lwdg
  129.             )
  130.             (vl-every
  131.               (function (lambda (x) (member-fuzz x lwrdxf10dxf42g 1e-4)))
  132.               lwdg
  133.             )
  134.           )
  135.            (setq e lwe)
  136.         )
  137.       )
  138.       (entdel (entlast))
  139.       (if e (sssetfirst nil (ssadd e)))
  140.     )
  141.   )
  142.   (princ)
  143. )
  144.  
« Last Edit: October 25, 2014, 01:22:21 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
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))
  4.             (sssetfirst nil (ssadd e))
  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.             (length
  34.                 (vl-remove 'nil
  35.                     (mapcar
  36.                        '(lambda ( a b ) (inters p (mapcar '+ p '(1e8 0.0)) a b))
  37.                         (cons (last l) l)
  38.                         l
  39.                     )
  40.                 )
  41.             )
  42.         )
  43.     )
  44. )

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
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:
http://ww3.cad.de/foren/ubb/Forum145/HTML/000602.shtml#000008

Try KGA_Geom_PointInsidePointList_P instead:
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.       (apply
  9.         '+
  10.         (mapcar
  11.           '(lambda (pt1 pt2)
  12.             (KGA_Geom_Angle pt1 pt pt2)
  13.           )
  14.           ptLst
  15.           (append (cdr ptLst) (list (car ptLst)))
  16.         )
  17.       )
  18.     )
  19.   )
  20. )
  21.  
  22. ; 20140220
  23. ; Return value: -pi <= angle <= pi
  24. (defun KGA_Geom_Angle (pt1 pt2 pt3 / ang)
  25.   (cond
  26.     ((<= (- pi) (setq ang (- (angle pt2 pt3) (angle pt2 pt1))) pi)
  27.       ang
  28.     )
  29.     ((minusp ang)
  30.       (+ ang pi pi)
  31.     )
  32.     (T
  33.       (- ang pi pi)
  34.     )
  35.   )
  36. )

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
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: 319
  • The most I miss IRL is the Undo button
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.

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
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

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
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

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
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)

:)

M.R. on Youtube

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
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

  • Swamp Rat
  • Posts: 1452
  • Marco
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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #15 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>

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Fasted way to find a closed polyline by point inside
« Reply #16 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.
...

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
Re: Fasted way to find a closed polyline by point inside
« Reply #17 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?
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #18 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)...

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
Re: Fasted way to find a closed polyline by point inside
« Reply #19 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]
« Last Edit: October 06, 2014, 12:38:39 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Fasted way to find a closed polyline by point inside
« Reply #20 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #21 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #22 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #23 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

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: Fasted way to find a closed polyline by point inside
« Reply #24 on: October 06, 2014, 05:22:33 PM »
The raycasting method has a fundamental flaw:
http://ww3.cad.de/foren/ubb/Forum145/HTML/000602.shtml#000008

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

Don't expect it to be fast though!

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
Re: Fasted way to find a closed polyline by point inside
« Reply #25 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.       (progn
  19.         (setq obj1 (vlax-ename->vla-object entn))
  20.         (setq obj2 (car (vlax-invoke obj1 'Offset 0.001))
  21.               obj3 (car (vlax-invoke obj1 'Offset -0.001))
  22.         )
  23.         (if (> (vla-get-area obj2) (vla-get-area obj3))
  24.           (progn
  25.             (set 'big obj2)
  26.             (set 'small obj3)
  27.           )
  28.           (progn
  29.             (set 'big obj3)
  30.             (set 'small obj2)
  31.           )
  32.         )
  33.         (setq p1 (vlax-curve-getClosestPointTo big pt)
  34.               p2 (vlax-curve-getClosestPointTo small pt)
  35.         )
  36.         (if (> (distance pt p1) (distance pt p2))
  37.           (setq flag T)
  38.           (setq flag nil)
  39.         )
  40.         (mapcar (function (lambda (x)
  41.                             (progn
  42.                               (vla-delete x)
  43.                               (vlax-release-object x)
  44.                             )
  45.                           )
  46.                 )
  47.                 (list big small)
  48.         )
  49.       )
  50.     )
  51.     flag
  52.   )
  53.  
  54.   (setq el (entlast))
  55.   (setq ss (ssget "_A"
  56.                   (list '(0 . "LWPOLYLINE")
  57.                         (cons 8 layer)
  58.                         '(-4 . "&=")
  59.                         '(70 . 1)
  60.                         (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model"))
  61.                   )
  62.            )
  63.   )
  64.   (command "_.SELECT" ss "")
  65.   (command "_.-BOUNDARY"     "_A"     "_B"     "_N"     "_P"
  66.            ""       "_I"     "_N"     ""       "_O"     "_P"
  67.            "_X"     pt       ""
  68.           )
  69.   (if (not (eq el (entlast)))
  70.     (progn
  71.       (setq lw (entlast))
  72.       (setq i -1)
  73.       (while (and (not e) (setq lwe (ssname ss (setq i (1+ i)))))
  74.         (if
  75.           (and
  76.             (vlax-invoke (vlax-ename->vla-object lw) 'intersectwith (vlax-ename->vla-object lwe) acextendnone)
  77.             (insidep pt lwe)
  78.           )
  79.           (setq e lwe)
  80.         )
  81.       )
  82.       (entdel (entlast))
  83.       (if e (sssetfirst nil (ssadd e)))
  84.     )
  85.   )
  86.   (princ)
  87. )
  88.  

Regards, M.R.
« Last Edit: October 25, 2014, 01:23:48 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Fasted way to find a closed polyline by point inside
« Reply #26 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...

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #27 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #28 on: October 07, 2014, 08:33:49 AM »
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!
Tested on Bricscad V15:
> 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.

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
Re: Fasted way to find a closed polyline by point inside
« Reply #29 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.
« Last Edit: October 07, 2014, 09:02:36 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Lee Mac

  • Seagull
  • Posts: 12913
  • London, England
Re: Fasted way to find a closed polyline by point inside
« Reply #30 on: October 07, 2014, 08:48:24 AM »
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!
Tested on Bricscad V15:

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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #31 on: October 07, 2014, 09:10:54 AM »
A messy attempt to avoid such issues:
...
Don't expect it to be fast though!
Tested on Bricscad V15:

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.

ribarm

  • Gator
  • Posts: 3272
  • Marko Ribar, architect
Re: Fasted way to find a closed polyline by point inside
« Reply #32 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...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Fasted way to find a closed polyline by point inside
« Reply #33 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.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1452
  • Marco
Re: Fasted way to find a closed polyline by point inside
« Reply #34 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
   adjacent. Anyway thanks again for your suggestions and tests!

Marco