如何确定点是否为
有人知道lisp或确定点是否在任意形状的闭合二维边界内(或外)的方法吗?编辑:嗯,我一发布,就看到了以前关于这个主题的帖子列表。我要学习一段时间。感谢所有以前的海报。 试一试:
我在编写这个程序时遇到了一件奇怪的事情:我的第一个版本使用了嵌套的重复循环。一旦它开始工作,我注意到,在同一个绘图会话中,每次试验的执行时间都有规律地增加。有了一张新的图纸,时钟被重置了。经过一番研究,我得出结论,将内部或外部循环更改为WHILE可以消除执行时间的延长。因此,至少对于Intellicad的Lisp实现,建议不要使用嵌套重复循环,如果程序将在同一个图形中重复使用,否则性能将逐渐下降。我想知道Autolisp或Visual lisp是否如此。 In my opinion, I doubt you will have success in finding a solution without using Visual LISP or vast amounts of coding. :wink: Here is what I came up with.
; boundpt.lsp - to test the method of checking for a point within a bounding ; polygon by counting the intersections of a ray drawn from the; point to be checked with the boundary.; A point within the boundary will always have an odd number; of intersections of the ray with the boundary. A point ; outside will always have an even number of intersections of; the ray with the boundary. This is true regardless of the; complexity of the boundary topology.; There are, of course, potential problems that can occur.; For example, what is to be done when the ray intersects a; point just at the corner where a pair of segments meets?; Or if the ray aligns precisely with a segment? This program; handles these glancing cases by using multiple rays with a; majority vote determination of the total number of; intersections.; This program is limited to polygons of line segments only,; no polylines and no arcs. This demo program assumes the; drawing consists of one closed boundary with any number of; point entities distributed inside and outside the boundary.; All entities must be visible for proper operation. At the; end of processing, the set of all points within the; boundary is selected and highlighted.;; On a 1.6 MHz processor with 2 Gb RAM, and a boundary of 60; segments, this program checks about 26 points per second. ; random number generator to randomize the ray angles(defun rnd (/ modulus multiplier increment random) (if (not seed) (setq seed (getvar "DATE")) ) (setq modulus 65536 multiplier 25173 increment13849 seed(rem (+ (* multiplier seed) increment) modulus) random (/ seed modulus) )); main(defun c:bpt (/ sscl cl_ln n cl_ed cl_en points_1 points_2 raylen rayang pt ppt1 ppt2 copy_cl ipt ef ic vlist sumc xmx xmn pt ptset pt_ln pt_en pt_ed loc_points oldcolor boundset) (setq sscl (ssget "X" '((0 . "LINE")))) ; get set of all lines(if sscl (setq cl_ln (sslength sscl)))(setq n 0)(if sscl ; not nil, store start and end points in list(progn(repeat cl_ln (setq cl_en (ssname sscl n)) (setq cl_ed (entget cl_en)) (setq points_1 (cons (cdr (assoc 10 cl_ed)) points_1)) ; save start point (setq points_2 (cons (cdr (assoc 11 cl_ed)) points_2)) ; save end point (setq n (+ n 1)))))(setq xmx (getvar "EXTMAX"))(setq xmn (getvar "EXTMIN"))(setq raylen (distance xmx xmn))(setq boundset (ssadd)) ; initialize in-bounds point set(setq ptset (ssget "X" '((0 . "POINT"))))(if ptset (setq pt_ln (sslength ptset)))(setq n 0)(if ptset ; not nil, store X Y location of points in list(progn(repeat pt_ln (setq pt_en (ssname ptset n)) (setq pt_ed (entget pt_en)) (setq loc_points (cons (cdr (assoc 10 pt_ed)) loc_points)) ; save point location (setq n (+ n 1)))))(setq np (- pt_ln 1))(repeat pt_ln(setq pt (car loc_points))(setq loc_points (cdr loc_points))(setq vlist nil)(setq ic 0)(setq n 0)(setq rayang (* (/ pi 1.5) (rnd))) ; for 3 rays(repeat 3 ; simulate 3 lines at random angles (while (< n cl_ln) ; check every segment of boundary for intersection (setq ppt1 (nth n points_1)) (setq ppt2 (nth n points_2)) (setq ipt (inters pt (polar pt rayang raylen) ppt1 ppt2)) (if ipt (setq ic (+ ic 1)) ) (setq n (+ n 1))) ; end inner loop (if (= (- (/ ic 2.0) (fix (/ ic 2.0))) 0) (setq ef 1) (setq ef 0) ) (setq ic 0) (setq n 0) (setq vlist (cons ef vlist)) (setq rayang (+ rayang (/ pi 1.5) (* (/ pi 1.5) (rnd)))) ; get new angle) ; end outer loop(setq sumc (apply '+ vlist))(if (not (or (= sumc 0) (= sumc 3))) (progn (princ "\n **** vote taken ****") (if (> sumc 1) (setq ef 1) ; for 3 lines (setq ef 0) ) ))(if (= ef 0) (ssadd (ssname ptset np) boundset))(setq np (- np 1)))(sssetfirst boundset boundset)(setq sscl nil)(setq ptset nil)(setq boundset nil)(princ))One strange thing I encountered while writing this program : My first version used nested REPEAT loops. Once it was working, I noticed that the execution time increased in a regular way with every trial within the same drawing session. With a new drawing, the clock was, as it were, reset. After playing around a bit, I concluded that changing either the inner or outer loop to a WHILE eliminated the lengthening execution time. So at least for Intellicad's Lisp implementation, the advice is don't use nested REPEAT loops if the program will be used repeatedly in the same drawing, or performance will gradually degrade. I wonder if this is true with Autolisp or Visual lisp.
页:
[1]