;判断点是否在多边形内 (defun C:te2 (/ olderr en errmsg oldmode oce sl ss ss1 ename t0 ptlist pp) ;;定义错误函数和预处理-------------------- (vl-load-com) (setvar "errno" 0) (setq olderr *error*) (defun *error* (msg) (setq en (getvar "errno")) (setq errmsg (strcat "errno=" (itoa en) "\nError:" msg)) (alert errmsg) (setq *error* olderr) ) (graphscr) (setq oldmode (getvar "osmode")) (setq oce (getvar "cmdecho")) (setvar "cmdecho" 0) (command ".ucs" "W") ;;也可以用其他方式取得点集---------------- (setq sl '((0 . "POINT"))) (setq ss (ssget sl)) (setq t0 (getvar "TDUSRTIMER")) (setq ptlist (getpt ss)) (princ "\n构造点集用时") (princ (* (- (getvar "TDUSRTIMER") t0) 86400)) (princ "秒") (command "_.change" ss "" "P" "C" "BYL" "") (princ "\n请选择多边形:") (setq ss1 (ssget ":S" '((-4 . "<OR")(0 . "POLYLINE")(0 . "LWPOLYLINE")(-4 . "OR>")))) (setq ename (if (= ss1 nil) nil (ssname ss1 0))) (if (= ename nil) (progn (alert "你没有选择多边形!") (command ".ucs" "P") (setvar "osmode" oldmode) (setvar "cmdecho" oce) (princ) ) (progn (setq pl (xdl-pl-vertexs ename)) ;;查找区域中的点并对用时进行估算------ (setq t0 (getvar "TDUSRTIMER")) (setq pp (search ptlist pl)) (princ "\n查找点用时") (princ (* (- (getvar "TDUSRTIMER") t0) 86400)) (princ "秒") (if (= nil pp) (progn (alert "在这个区域没有点集中的点!") (command ".ucs" "p") (setvar "osmode" oldmode) (setvar "cmdecho" oce) (princ) ) (progn ;;改变查找出来的点的颜色为红色---- (setvar "osmode" 0) (setq t0 (getvar "TDUSRTIMER")) (change-color ss pp 1) (princ "\n点变色用时") (princ (* (- (getvar "TDUSRTIMER") t0) 86400)) (princ "秒") (command ".ucs" "P") (setvar "osmode" oldmode) (setvar "cmdecho" oce) (princ) ) ) ) ) ) ;;;***************************************** ;;;定义查找函数2,并获得每个点的坐标和原编号 (defun search (ptlist pl / pp ex) (setq pp nil) (foreach n ptlist (if (ptinpm n pl) (setq pp (cons n pp)) ) ) pp ) ;;;***************************************** ;;依据晓东网站的代码改写而成的取点函数------ (defun getpt (ss / i listpp a b c) (setq i 0 listpp nil) (if ss (repeat (sslength ss) (setq a (ssname ss i) b (entget a) c (cdr (assoc 10 b)) c (list (car c) (cadr c) i) ) ;;i用来定义在选择集中的编号,不是Z坐标 (setq listpp (cons c listpp)) (setq i (1+ i)) ) ) (reverse listpp) ) ;;定义改变查找到的点的颜色的函数------------ (defun change-color (ss pp color / i) (setq i 0) (foreach n pp (setq a (ssname ss (caddr n))) (setq b (entget a)) (setq b (cons (cons 62 color) b)) (entmod b) ) ) ;;取得多边形顶点------------------感谢eachy! (defun xdl-pl-vertexs (e / n lst) (if (= e nil) nil (progn (setq lst (repeat (setq n (fix (1+ (vlax-curve-getendparam (vlax-ename->vla-object e))))) (setq lst (cons (vlax-curve-getpointatparam (vlax-ename->vla-object e) (setq n (1- n))) lst)) ) ) (if (= 0 (cdr (assoc 70 (entget e)))) lst (cdr lst) ) ) ) ) ;;判断点是否在多边形内-------------感谢狂刀! (defun ptinpm (pt lst) (equal PI (abs (apply '+ (mapcar '(lambda (x y) (rem (- (angle pt x) (angle pt y)) PI)) (reverse (cdr (reverse (cons (last lst) lst)))) lst ) ) ) 1e-6 ) ) 程序如上: 但是本人对狂刀兄的这个函数百思不得其解,按照我对函数实现的理解是把所有相邻顶点和要测试的点形成的夹角取和, 问题是取和之后怎么会是等于PI呢?表面上看取和等于2PI(也就是360度)实际上很多情况也不会等于2PI。我硬是没想通! |