Author Topic: Is a Point inside a polyline? (Not with ssget CP (list vertexes Polyline) )  (Read 4485 times)

0 Members and 1 Guest are viewing this topic.

Amsterdammed

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


Fatty

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

Amsterdammed

  • Guest
Fatty,
interresting approach (typical no nonsens Russian approach i guess  :wink:). Pretty logical if you look at it, never thought that direction.

Thanks :-)

Swift

  • Swamp Rat
  • Posts: 596
The ideal in computational geometry is


whdjr

  • Guest
There is a lot of usefull infor mation here.

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
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)
)
« Last Edit: November 04, 2005, 02:02:17 PM by Jeff_M »

Fatty

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

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
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

Bob Wahr

  • Guest
Another poor implementation of 3D by Autodesk?

Andrea

  • Water Moccasin
  • Posts: 2372
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.
« Last Edit: October 08, 2013, 04:10:41 PM by Andrea »
Keep smile...

VovKa

  • Water Moccasin
  • Posts: 1628
  • Ukraine