PDA

View Full Version : Autolisp function to determine point location



BrenBren
2008-02-28, 10:01 PM
Summary: An Autolisp function to determine if a point is inside a closed polyline or selection set of objects.

Description: I wish there was an autolisp function to determine if a point is "inside" a closed polyline or selection set of objects.

How Used: Having such a function would fill a gap in the current function list, and would eliminate ~200 lines of code (at least in my case) for lisp programs that require that test, making it more efficient.

Submitted By: Tim Creary on January 16, 2008

Lee Mac
2009-05-17, 02:53 PM
I agree, this would be a great addtion.

I currently use this, which I wrote a while back, but it is no way fool-proof:




;; ============ Insidep.lsp ===============
;;
;; MAIN FUNCTION DESCRIPTION:
;; Will determine whether a point lies
;; inside or outside an object.
;;
;; FUNCTION: insidep
;; ARGUMENTS:
;; Point to be tested.
;; Object Ename or VLA-Object
;;
;; FUNCTION: vlax-list->3D-point
;; ARGUMENTS:
;; List to be converted.
;; Flag to determine x or y.
;;
;; OBJECT COMPATIBILITY:
;; Everything except Viewport/Polygon Mesh.
;;
;; AUTHOR:
;; Copyright (c) 2009, Lee McDonnell
;; (Contact Lee Mac, CADTutor.net)
;;
;; PLATFORMS:
;; No Restrictions,
;; only tested in ACAD 2004.
;;
;; ========================================

(defun insidep (pt Obj / Obj Tol ang doc spc flag int lin xV yV)
(vl-load-com)

(or (eq 'VLA-OBJECT (type Obj))
(setq Obj (vlax-ename->vla-object Obj)))

(setq Tol (/ pi 6) ; Uncertainty
ang 0.0 flag T)

(setq doc (vla-get-ActiveDocument (vlax-get-Acad-Object))
spc (if (zerop (vla-get-activespace doc))
(if (= (vla-get-mspace doc) :vlax-true)
(vla-get-modelspace doc)
(vla-get-paperspace doc))
(vla-get-modelspace doc)))

(while (and (< ang (* 2 pi)) flag)
(setq flag (and
(setq int
(vlax-invoke
(setq lin
(vla-addLine spc
(vlax-3D-point pt)
(vlax-3D-point
(polar pt ang
(if (vlax-property-available-p Obj 'length)
(vla-get-length Obj) 1.0)))))
'IntersectWith Obj
acExtendThisEntity))
(<= 6 (length int))
(setq xV (vl-sort (vlax-list->3D-point int T) '<)
yV (vl-sort (vlax-list->3D-point int nil) '<))
(or (<= (car xV) (car pt) (last xV))
(<= (car yV) (cadr pt) (last yV))))
ang (+ ang Tol))
(vla-delete lin))
flag)

(defun vlax-list->3D-point (lst flag)
(if lst
(cons ((if flag car cadr) lst)
(vlax-list->3D-point (cdddr lst) flag))))

;; Test Function

(defun c:test (/ pt ss)
(sssetfirst nil nil)
(if (and (setq pt (getpoint "\nSelect Point Within Boundary: "))
(setq ss (ssget "X" (list (cons 0 "~VIEWPORT")
(if (getvar "CTAB")
(cons 410 (getvar "CTAB"))
(cons 67 (- 1 (getvar "TILEMODE"))))))))
(progn
(princ "\nSelecting Everything Visible...\nAnalyzing Surrounding Region...")
(foreach ent (mapcar 'cadr (ssnamex ss))
(if (not (insidep pt ent))
(ssdel ent ss)))
(if (not (zerop (sslength ss)))
(sssetfirst nil ss)
(princ "\nPoint Does not lie Within Boundary!")))
(princ "\n<!> No Point Selected or No Objects in Drawing <!>"))
(princ))

BlackBox
2010-09-28, 03:45 PM
Along the lines of point location functions...

It would also be great if there were an easy way to determine the 'inside' center of all vertexes that make up a polyline (not the centroid!). A new ActiveX property or method, perhaps?

For example, given a "C" or an "L" shaped polyline, the centroid resides outside of the polyline.