革天明 发表于 2017-10-18 18:20:25

求助数学问题,如何判断三维点在另外三个三维点构成的平面上的投影点,是否在三角形内

本帖最后由 革天明 于 2017-10-18 18:25 编辑


如图所示,三维点A、B、C构成平面ABC,三维点P在平面ABC上的投影点为P'(有可能与P重合-当P在ABC平面上时),如何判断P‘是否在三角形ABC内?若P’在ABC三角形的任意一边上,也视为在三角形ABC内。
我参考http://www.cnblogs.com/flyinghea ... /07/14/2106892.html此处的方法,未得到正确的返回结果,可使用A(0,0,0),B(10,0,-7),C(5,10,15),P(5,5,3)来测试。

fools 发表于 2017-10-18 23:40:30

本帖最后由 fools 于 2017-10-19 12:50 编辑

可先将空间点投影到平面上,再对共面的4点进行判断
2017.10.19修改了PtInTriangle,避免整数除整数出错

;;;测试程序
(defun c:tt (/ A B C P)
(setq   A '(0 0 0)
      B '(10 0 -7)
      C '(5 10 15)
      P '(5 5 3)
)
(if (PtInTriangle (ClosestPointonPlane P A B C) A B C)
    (alert "点在三角形内")
    (alert "点在三角形外")
)
(princ)
)
;;;http://www.blackpawn.com/texts/pointinpoly/default.html
;;;重心法判别点是否在三角形内
(defun PtInTriangle (p pa pb pc / DENO U V V0 V1 V2 VV00 VV01 VV02 VV11 VV12)
(setq v0 (MAT:v-v pc pa))
(setq v1 (MAT:v-v pb pa))
(setq v2 (MAT:v-v p pa))
(setq vv00 (MATDOT v0 v0))
(setq vv01 (MATDOT v0 v1))
(setq vv02 (MATDOT v0 v2))
(setq vv11 (MATDOTv1 v1))
(setq vv12 (MATDOT v1 v2))
(setq deno (- (* vv00 vv11) (* vv01 vv01)))
(setq u (/ (- (* vv11 vv02) (* vv01 vv12)) deno 1.0))
(setq v (/ (- (* vv00 vv12) (* vv01 vv02)) deno 1.0))
(if (and (>= u 0) (>= v 0) (<= (+ u v) 1))
    T
    nil
)
)
;;;https://www.theswamp.org/index.php?topic=36786.0
;;;获取平面中距离空间点最近的点(空间点到平面的垂点)
(defun ClosestPointonPlane (pt p1 p2 p3)
((lambda (n) (setq pt (trans pt 0 n)) (trans (list (car pt) (cadr pt) (caddr (trans p1 0 n))) n 0))
    (MAT:vxv (MAT:v-v p2 p1) (MAT:v-v p3 p1))
)
)
;;;向量差
(defun MAT:v-v (v1 v2) (mapcar '- v1 v2))
;;;向量点积
(defun MATDOT (v1 v2) (apply '+ (mapcar '* v1 v2)))
;;;向量叉积
(defun MAT:vxv (u v)
(list      (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
      (- (* (car v) (caddr u)) (* (car u) (caddr v)))
      (- (* (car u) (cadr v)) (* (car v) (cadr u)))
)
)
(princ)






lijiao 发表于 2017-10-23 09:58:28

(setq A '(0 0 0)
      B '(10 0 -7)
      C '(5 10 15)
      P '(5 5 3)
      )

(command "ucs" "")
(command "ucs" a b c)
(setq a1 (trans a 0 1))
(setq b1 (trans b 0 1))
(setq c1 (trans c 0 1))
(setq p1 (trans p 0 1))
(setq a1 (list (car a1) (cadr a1))
      b1 (list (car b1) (cadr b1))
      c1 (list (car c1) (cadr c1))
      p1 (list (car p1) (cadr p1))
      )
(command "ucs" "")
(command "pline" a1 b1 c1 "c")
(setq plent (vlax-ename->vla-object (entlast)))
(setq e0 (vla-get-Area plent))
(vlax-put plent 'Coordinates (append a1 b1 p1))
(setq e1 (vla-get-Area plent))
(vlax-put plent 'Coordinates (append c1 b1 p1))
(setq e2 (vla-get-Area plent))
(vlax-put plent 'Coordinates (append a1 c1 p1))
(setq e3 (vla-get-Area plent))
(vla-delete plent)
(command "ucs" "p")
(command "ucs" "p")
(command "ucs" "p")
(>= e0 (+ e1 e2 e3))

革天明 发表于 2017-10-19 11:40:46

本帖最后由 革天明 于 2017-10-19 11:45 编辑

fools 发表于 2017-10-18 23:40
可先将空间点投影到平面上,再对共面的4点进行判断
(if (and (>= u 0) (>= v 0) (<= (+ u v) 1))
这里的等号是否决定了在三条边上也判定为在三角形内?
_$ (PtInTriangle (list 0 -3 0) (list 0 0 0) (list 10 0 0) (list 10 10 0) )
T

这个返回值应该不正确,点没有在三角形内,返回值却为T

fools 发表于 2017-10-19 12:44:21

嗯,整数除整数返回整数,出错了,这两句修改下,加上1.0
(setq u (/ (- (* vv11 vv02) (* vv01 vv12)) deno 1.0))
(setq v (/ (- (* vv00 vv12) (* vv01 vv02)) deno 1.0))


u=0或v=0或u+v=1表示在边上
u=v=0或u=1,v=0或u=0,v=1表示在点上

;;重心法判别点是否在三角形内
(defun PtInTriangle (p pa pb pc / DENO U V V0 V1 V2 VV00 VV01 VV02 VV11 VV12)
(setq v0 (MAT:v-v pc pa))
(setq v1 (MAT:v-v pb pa))
(setq v2 (MAT:v-v p pa))
(setq vv00 (MATDot v0 v0))
(setq vv01 (MATDot v0 v1))
(setq vv02 (MATDot v0 v2))
(setq vv11 (MATDot v1 v1))
(setq vv12 (MATDot v1 v2))
(setq deno (- (* vv00 vv11) (* vv01 vv01)))
(setq u (/ (- (* vv11 vv02) (* vv01 vv12)) deno 1.0))
(setq v (/ (- (* vv00 vv12) (* vv01 vv02)) deno 1.0))
(if (and (>= u 0) (>= v 0) (<= (+ u v) 1))
    T
    nil
)
)

pengfei2010 发表于 2017-10-21 08:55:57

回帖是一种美德!感谢楼主的无私分享 谢谢

xyp1964 发表于 2017-10-21 13:23:54

本帖最后由 xyp1964 于 2017-10-21 13:28 编辑

(defun Mid2Pt (p1 p2)
(mapcar '(lambda (x y) (* (+ x y) 0.5)) p1 p2)
)
(defun abc (p a b c / pab pac pbc p1 p2 p3)
(setqpab (Mid2Pt a b)
pac (Mid2Pt a c)
pbc (Mid2Pt c b)
p1(Mid2Pt pab c)
p2(Mid2Pt pac b)
p3(Mid2Pt pbc a)
)
(and (<= (distance p p1) (distance p c))
       (<= (distance p p1) (distance p pab))
       (<= (distance p p2) (distance p b))
       (<= (distance p p2) (distance p pac))
       (<= (distance p p3) (distance p a))
       (<= (distance p p3) (distance p pbc))
)
)

(setq a'(0 0 0)
      b'(10 0 -7)
      c'(5 10 15)
      p'(5 5 3)
)
(abc p a b c)

fools 发表于 2017-10-21 17:27:33

院长,这样判断不行,三星形内靠近端点的区域会出错

evayleung 发表于 2017-10-21 22:55:34

角APB,角BPC,角CPA,之和=360度时,P点在三角形内,小于360度时在三角形外。

fools 发表于 2017-10-22 22:43:27

p与c距离小于p与p1,但p在三角形内

cabinsummer 发表于 2017-10-23 08:28:03

不能坐标变换后再判断吗?
页: [1] 2
查看完整版本: 求助数学问题,如何判断三维点在另外三个三维点构成的平面上的投影点,是否在三角形内