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

0 Members and 1 Guest are viewing this topic.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • 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: 1451
  • 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: 3225
  • 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: 12906
  • 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: 1451
  • 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: 3225
  • 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: 1451
  • 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: 1451
  • 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.