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)
)