@marko_ribar
Here is my ancient and well worn @inside function, complete with remarks.
It is a function internal to my QuickArea command function to label the area of polylines just by picking any point inside.
I timed it on a 29 vertex LWPoly with plenty of inward and outward bulges at 2.70 sec. for 1000 iterations.
Unless I am mistaken, Lee Mac's IS_INSIDE function does not deal with bulged segments.
When I ran his function I got:
Command: (is_inside p pts) TRIANGLST
I don't know if that is equal to T (as in true) or what.
I have not studied or tested the rest of the OP's code as I was looking for just obvious speed improvements.
(defun @Inside (PIQ Object / Closest Start End Param P
a1 a2 Defl @2D @Bulge)
;; "LOOK, MA'... NO RAYS!"
;; @Inside.lsp v1.0 (09-15-03) John F. Uhden, Cadlantic.
;; v2.0 Revised (09-17-03) - See notes below.
;; v3.0 Revised (09-20-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°, and if outside 0°
;; (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.5) ; 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))
)
)
)
;; Function to convert a 3D point into 2D for the purpose
;; of ignoring the Z value.
;; Added (09-20-03)
(defun @2D (p)(list (car p)(cadr p)))
;;-----------------------------------------------------
;; Function to determine if an angle is with the sector
;; defined by two other angles.
;; Returns the delta angle from the first angle.
;;
(defun @insect (Ang Ba Ea)
(if (> Ba Ea)
(cond
((>= Ang Ba))
((<= Ang Ea))
(1 nil)
)
(< Ba Ang Ea)
)
)
(defun @Bulge (Param / Bulge V1 V2 Half Delta Chord Radius Center Ba Ea Ang P)
(and
(setq Bulge (vl-catch-all-apply 'vla-getbulge (list Object (fix Param))))
(numberp Bulge)
(/= Bulge 0)
(< Param End)
(setq V1 (vlax-curve-getpointatparam Object (fix Param)))
(setq V2 (vlax-curve-getpointatparam Object (1+ (fix Param))))
(setq V1 (trans V1 0 1))
(setq V2 (trans V2 0 1))
(setq Half (if (minusp Bulge) -0.5 0.5)
Delta (* 4.0 (atan (abs Bulge)))
Chord (distance V1 V2)
Radius (/ Chord 2 (sin (/ Delta 2)))
Center (polar V1 (+ (angle V1 V2)(* (- pi Delta) Half)) Radius)
)
(if (minusp Bulge)
(setq Ba (angle Center V2) Ea (angle Center V1))
(setq Ba (angle Center V1) Ea (angle Center V2))
)
(setq Ang (angle Center PIQ))
(@insect Ang Ba Ea)
(setq P (polar Center Ang Radius))
)
P
)
(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 Closest
(vlax-curve-getclosestpointto Object P) ; In WCS
)
;; Test to see if PIQ is on object:
(not (equal (@2D P)(@2D Closest) 1e-10)) ; in WCS
(setq End (vlax-curve-getEndparam Object))
(if (= (vla-get-objectname Object) "AcDbSpline")
(setq Sample (/ End 100))
(setq Sample 1.0)
)
(setq Param Sample Defl 0.0)
(setq a1 (angle PIQ (trans Start 0 1))) ; in UCS
(while (<= Param End)
(setq Param (min Param End))
(setq P (vlax-curve-getpointatparam Object Param)
a2 (angle PIQ (trans P 0 1)) ; in UCS
Defl (+ Defl (@delta a1 a2))
a1 a2
)
; (grdraw PIQ P 3)
(if (setq P (@Bulge Param))
(progn
;(grdraw PIQ (trans (vlax-curve-getpointatparam Object P1) 0 1) 1)
;(grdraw PIQ P 1)
;(grdraw PIQ (trans (vlax-curve-getpointatparam Object P2) 0 1) 3)
(setq a2 (angle PIQ P)
Defl (+ Defl (@delta a1 a2))
a1 a2
)
)
)
(setq Param (+ Param Sample))
)
;(print Defl) ; Optional display of results
(> (abs Defl) 4)
)
)