TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started 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
-
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
;;======================================================================;;
;; 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
-
Fatty,
interresting approach (typical no nonsens Russian approach i guess :wink:). Pretty logical if you look at it, never thought that direction.
Thanks :-)
-
The ideal in computational geometry is
(http://www.survey-this.com/Images/PtInPoly.JPG)
-
There is a lot of usefull infor mation here (http://www.theswamp.org/forum/index.php?topic=1890.0).
-
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.
(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)
)
-
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
-
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
-
Another poor implementation of 3D by Autodesk?
-
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.
(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.
-
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)