TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Amsterdammed on November 04, 2005, 08:43:38 AM

Title: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Amsterdammed on November 04, 2005, 08:43:38 AM
Hello again,

For an application I work on I need to determinate is an End- or Start point of a curve lies in a certain closed Polyline.

So what I do now is selecting with the bounding box of the curve the possible polyline where my Start en End points can be in. Than I draw a temp. Point in the End en Start point of the curve and with

Ssget CP (list of vertexes Polyline)

I find out if the point is a member of the ss.

But I wonder if there is a more elegant way to do so?

Thanks in Advance

Bernd

Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Fatty on November 04, 2005, 10:10:58 AM
Hello again,

For an application I work on I need to determinate is an End- or Start point of a curve lies in a certain closed Polyline.

So what I do now is selecting with the bounding box of the curve the possible polyline where my Start en End points can be in. Than I draw a temp. Point in the End en Start point of the curve and with

Ssget CP (list of vertexes Polyline)

I find out if the point is a member of the ss.

But I wonder if there is a more elegant way to do so?

Thanks in Advance

Bernd



Hi Bernd

See this routine I wrote some time ago

Code: [Select]
;;======================================================================;;
;; DETERMINING IF A POINT LIES ON THE INTERIOR OF A POLYGON ;;
;;======================================================================;;

;;  Idea was stoled from Eugeny Kalney
;;  http://www.k-prof.com.ru/
;;  written by Fatty The Old Horse
;;  9/29/05 edited: 9/30/05

(defun insidep (pt ent / big flag obj1 obj2 obj3 p1 p2 small)
  (vl-load-com)
  (if (and pt ent)
    (progn
      (setq obj1 (vlax-ename->vla-object (car ent)))
      (setq obj2 (car (vlax-invoke obj1 'Offset 0.001))
    obj3 (car (vlax-invoke obj1 'Offset -0.001)))
      (if (> (vla-get-area obj2)(vla-get-area obj3))
(progn
  (set 'big obj2)
  (set 'small obj3))
(progn
  (set 'big obj3)
  (set 'small obj2)))
      (setq p1 (vlax-curve-getClosestPointTo big pt)
    p2 (vlax-curve-getClosestPointTo small pt))
      (if (> (distance pt p1)(distance pt p2))
(setq flag T)
(setq flag nil))
      (mapcar (function (lambda (x)
  (progn
    (vla-delete x)
    (vlax-release-object x))))
      (list big small))
      )
    )
  flag
   )

Thank you

Fatty
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Amsterdammed on November 04, 2005, 10:27:22 AM
Fatty,
interresting approach (typical no nonsens Russian approach i guess  :wink:). Pretty logical if you look at it, never thought that direction.

Thanks :-)
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Swift on November 04, 2005, 10:32:59 AM
The ideal in computational geometry is

(http://www.survey-this.com/Images/PtInPoly.JPG)
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: whdjr on November 04, 2005, 11:03:24 AM
There is a lot of usefull infor mation here (http://www.theswamp.org/forum/index.php?topic=1890.0).
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Jeff_M on November 04, 2005, 12:01:08 PM
Here's a pretty thorough routine written by John Uhden and posted to the Autodesk newsgroup a few years back. It is based on the theory that Swift posted.
Code: [Select]
(defun @Inside (PIQ Object / ClosestPoint ClosestParam Sample
                             Start End P1 P2 P a1 a2 Defl)
  ;;               "LOOK, MA... NO RAYS!"
  ;; @Inside.lsp v1.0 (09-15-03) John F. Uhden, Cadlantic.
  ;; v2.0 Revised (09-17-03) - See notes below.
  ;; Function to determine whether a point is inside the boundary
  ;; of a closed curve.
  ;; It employs the theorem that the sum of the deflections of a
  ;; point inside the curve should equal 360=B0, and if outside 0=B0
  ;; (both absolute values).
  ;; The results with Ellipses were fairly rough, and the results
  ;; with a Spline were very rough, thus the fuzz factor of 2.
  ;;
  ;; Arguments:
  ;;   PIQ    - Point to test (2D or 3D point as a list in UCS)
  ;;   Object - Curve to test (Ename or VLA-Object)
  ;;
  ;; Returns:
  ;;   T   (if the PIQ is inside the curve)
  ;;   nil (if either the arguments are invalid,
  ;;       or the PIQ is on or outside the curve)
  ;;
  ;; NOTES:
  ;;   Requires one or another version of the @delta function,
  ;;     such as included here.
  ;;   It will not work well with self-intersecting (overlapping)
  ;;     bulged polyline segments.
  ;;   Curves can be CIRCLEs, ELLIPSEs, LWPOLYLINEs, POLYLINES,
  ;;     SPLINEs, and maybe even more.
  ;;   Thanks already to Doug Broad for finding bugs.
  (setq Sample 0.2) ; this is better for bulged polylines.
  ;;   Sure, you could decrease the sampling from 0.5 to say 0.1,
  ;;     but it will only slow down the process and still not
  ;;     guarantee success with overlapping bulged segments.
  ;;   DO NOT change the sampling value to anything that is
  ;;     greater than 1 or not evenly divisible into 1, as you
  ;;     would not be sampling vertices.
  ;;   (09-17-03) Found that cusps brought back inside the figure
  ;;     yield a total deflection of (* pi 2), so changed evaluation
  ;;     to see if deflection was greater than 4, which is
  ;;     equivalent to a fuzz factor of 2.28 from (* pi 2).
  (vl-load-com)
  (or (= (type @delta) 'SUBR)
    (defun @delta (a1 a2)
      (cond
        ((> a1 (+ a2 pi))
          (+ a2 pi pi (- a1))
        )
        ((> a2 (+ a1 pi))
          (- a2 a1 pi pi)
        )
        (1 (- a2 a1))
      )
    )
  )
  (and
    (cond
      ((not Object)
        (prompt "  No object provided.")
      )
      ((= (type Object) 'VLA-Object))
      ((= (type Object) 'Ename)
        (setq Object (vlax-ename->vla-object Object))
      )
      (1 (prompt "  Improper object type."))
    )
    (or
      (and
        (< 1 (vl-list-length PIQ) 4)
        (vl-every 'numberp PIQ)
      )
      (prompt " Improper point value.")
    )
    (or
      (not
        (vl-catch-all-error-p
          (setq Start
            (vl-catch-all-apply
              'vlax-curve-getStartPoint
              (list Object)
            )
          )
        )
      )
      (prompt "  Object is not a curve.")
    )
    (or
      (equal Start (vlax-curve-getendpoint Object) 1e-10)
      (prompt "  Curve is not closed.")
    )
    (setq P (trans PIQ 1 0)) ; PIQ in WCS
    (setq ClosestPoint
      (vlax-curve-getclosestpointto Object P) ; In WCS
    )
    (not (equal P ClosestPoint 1e-10)) ; in WCS
    (setq ClosestParam (vlax-curve-getparamatpoint Object ClosestPoint))
    (setq ClosestPoint (trans ClosestPoint 0 1)) ; convert to UCS
    (setq End (vlax-curve-getEndparam Object))
    (setq P1 0.0 P2 Sample Defl 0.0)
    (setq a1 (angle PIQ (trans Start 0 1))) ; in UCS
    (while (<= P2 End)
      (setq P2 (min P2 End))
      ;; This little extra makes sure not to skip an angle
      ;; that might throw off the total deflection.
      ;; Moved to near top of while loop in case ClosestParam
      ;; is less than the first sample.
      (if (< P1 ClosestParam P2)
        (setq a2 (angle PIQ ClosestPoint)
              Defl (+ Defl (@delta a1 a2))
              a1 a2
        )
      )
      ;; The following (while) loop takes care of
      ;; coincident adjacent vertices.
      (while (not (setq P (vlax-curve-getPointAtParam Object P2)))
        (setq P2 (+ P2 Sample))
      )
      (setq a2 (angle PIQ (trans P 0 1)) ; in UCS
          Defl (+ Defl (@delta a1 a2))
          a1 a2
          P1 P2
          P2 (+ P2 Sample)
      )
    )
    ;(print Defl) ; Optional display of results
    (> (abs Defl) 4)
  )
)
;;;;;;*************
(defun C:ITest ( / Object P)
  (if (setq Object (car (entsel "\nSelect curve: ")))
    (while (setq P (getpoint "\nPoint: "))
      (prin1 (@Inside P Object))
    )
  )
  (princ)
)
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Fatty on November 04, 2005, 12:58:16 PM
Hi Jeff!

After I loaded J.Uhnden's function I have got following message:

; error: no function definition: =3D

Can you send this local function on forum?
Thank you
Fatty
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Jeff_M on November 04, 2005, 02:04:39 PM
Hi Fatty,
That was a glitch in the Autodesk forum's software! Somehow it placed "3D" after every "=" sign. I just modified the code above to fix this. If you find any more, let me know...but I think I got them all.

Jeff
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Bob Wahr on November 04, 2005, 02:09:08 PM
Another poor implementation of 3D by Autodesk?
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: Andrea on October 08, 2013, 03:27:55 PM
My contribution..

sorry,...I know this is an Old topic,..but just want to put same information in the same place,...I think this will help alot of searching for some info.
Code: [Select]
(defun @inside (coordonee entite / vla-line #lign1 #lign2 snapang numb lineEname varval ZX_ViewSize temppoint Inresult PolygonPoints)

(if (/= entite  Last_entite)
  (progn
(setq ZonePointList (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object entite)))))
(while (car ZonePointList)
  (setq PolygonPoints (append PolygonPoints (list (trans (list (car ZonePointList) (cadr ZonePointList)) 0 1))))
  (setq ZonePointList (cddr ZonePointList))
)
(setq PolygonPoints (mapcar '(lambda (x)
(vl-remove 0.0  x)
)
     PolygonPoints)) 
(if (not temppoint)
  (setq temppoint
(entmakex (list
     '(0 . "POINT")
     (cons 10 (trans coordonee 1 0))
     '(62 . 250)
     '(420 . 2765628)
     )
   )
)
  )
)
  (setq Last_entite entite)
  ) 

(if
(and PolygonPoints
     (listp PolygonPoints)
     (> (length PolygonPoints) 2)
)
(if (ssget "_WP" PolygonPoints '((0 . "POINT") (62 . 250)(420 . 2765628)))
    (setq Inresult T)
    (setq Inresult nil)
)
)
  (princ)
(if temppoint
  (progn
    (entdel temppoint)
    (setq temppoint nil)
  )

 
(if Inresult
  (alert "INSIDE")
  (alert "OUTSIDE")
  )
)


;;test
;;(@inside (getpoint) (car (entsel)))


I've tested many kind of this point detection...
but all program tested have issue when trying to zoom in having polygon outside the screen
or non-closed polygone..

so I use diffrent approach by making a point and detect that point wit "WPoly" following the Pline points.
seem to work well...but need your input.

thank you.
Title: Re: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )
Post by: VovKa on October 08, 2013, 05:29:07 PM
just in case someone needs the mathematical solution
http://www.cadtutor.net/forum/showthread.php?39199-Identify-a-polyline-by-a-point-inside-this-polyline&p=263330&viewfull=1#post263330 (http://www.cadtutor.net/forum/showthread.php?39199-Identify-a-polyline-by-a-point-inside-this-polyline&p=263330&viewfull=1#post263330)