本帖最后由 dtucad 于 2024-4-3 23:37 编辑
http://bbs.mjtd.com/thread-189728-1-1.html
跟随黄总的步伐,也来两个判断点在封闭曲线内的函数,水平有限,如有错误请反馈
- ;第一种
- ;判断点是否在非自交多边形内,使用射线交叉法,从要测试的点向任意方向引一条射线,统计射线与多边形边界的交点数量。如果交点数目是奇数,则点位于多边形内部;如果是偶数,则点位于多边形外部。如果交点为多边形顶点可能无法正确判断,此时旋转射线重新判断。
- ;参数:pt判断的点、pts多边形点表、fz误差
- ;返回:1在内部、0在线上、-1在外部
- (defun JudPtinPts (pt pts fz / box d i inter k line lines lines-tmp memberfz ray)
- (defun MemberFz (pt lst fz);带误差的member
- (vl-some (function (lambda(x) (equal pt x fz))) lst)
- )
-
- (setq lines (mapcar (function list) pts (append (cdr pts) (list (car pts)))))
- (if (vl-some ;判断点在线上
- (function (lambda (x / ang1 ang2 p1 p2)
- (setq p1 (car x))
- (setq p2 (cadr x))
- (or
- (or
- (equal pt p1 fz)
- (equal pt p2 fz)
- )
- (and
- (setq ang1 (angle p1 pt))
- (setq ang2 (angle pt p2))
- (or (equal ang1 ang2 1e-6)
- (equal (abs (- ang1 ang2)) (* pi 2) 1e-6)
- )
- )
- )
- )
- )
- lines
- )
- 0;在线上
- (progn;判断交点数量
- (setq box (mapcar (function (lambda (a b) (apply (function mapcar) (cons a b)))) '(min max) (list pts pts)))
- (setq d (+ (apply 'distance box) (distance pt (car pts))))
- (setq ray (list pt (polar pt 0 d)));虚拟一条足够长的射线
- (setq lines-tmp lines)
- (setq i 0 k 0)
- (while (and lines-tmp (< k 360))
- (setq line (car lines-tmp))
- (setq lines-tmp (cdr lines-tmp))
- (if (setq inter (apply 'inters (append ray line)));有交点
- (if (not (MemberFz inter pts fz));且交点不为顶点
- (setq i (1+ i));交点数量
- (setq i 0;归零
- k (1+ k)
- ray (list pt (polar pt (* (/ pi 180) k) d));射线旋转1°
- lines-tmp lines;重新判断
- )
- )
- )
- )
- (cond
- ((zerop (rem i 2)) -1);偶数个交点,在线外
- (t 1);奇数,在线内
- )
- )
- )
- )
|