明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3492|回复: 15

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

[复制链接]
发表于 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)来测试。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2017-10-18 23:40:30 | 显示全部楼层
本帖最后由 fools 于 2017-10-19 12:50 编辑

可先将空间点投影到平面上,再对共面的4点进行判断
2017.10.19修改了PtInTriangle,避免整数除整数出错
  1. ;;;测试程序
  2. (defun c:tt (/ A B C P)
  3.   (setq   A '(0 0 0)
  4.         B '(10 0 -7)
  5.         C '(5 10 15)
  6.         P '(5 5 3)
  7.   )
  8.   (if (PtInTriangle (ClosestPointonPlane P A B C) A B C)
  9.     (alert "点在三角形内")
  10.     (alert "点在三角形外")
  11.   )
  12.   (princ)
  13. )
  14. ;;;http://www.blackpawn.com/texts/pointinpoly/default.html
  15. ;;;重心法判别点是否在三角形内
  16. (defun PtInTriangle (p pa pb pc / DENO U V V0 V1 V2 VV00 VV01 VV02 VV11 VV12)
  17.   (setq v0 (MAT:v-v pc pa))
  18.   (setq v1 (MAT:v-v pb pa))
  19.   (setq v2 (MAT:v-v p pa))
  20.   (setq vv00 (MATDOT v0 v0))
  21.   (setq vv01 (MATDOT v0 v1))
  22.   (setq vv02 (MATDOT v0 v2))
  23.   (setq vv11 (MATDOT  v1 v1))
  24.   (setq vv12 (MATDOT v1 v2))
  25.   (setq deno (- (* vv00 vv11) (* vv01 vv01)))
  26.   (setq u (/ (- (* vv11 vv02) (* vv01 vv12)) deno 1.0))
  27.   (setq v (/ (- (* vv00 vv12) (* vv01 vv02)) deno 1.0))
  28.   (if (and (>= u 0) (>= v 0) (<= (+ u v) 1))
  29.     T
  30.     nil
  31.   )
  32. )
  33. ;;;https://www.theswamp.org/index.php?topic=36786.0
  34. ;;;获取平面中距离空间点最近的点(空间点到平面的垂点)
  35. (defun ClosestPointonPlane (pt p1 p2 p3)
  36.   ((lambda (n) (setq pt (trans pt 0 n)) (trans (list (car pt) (cadr pt) (caddr (trans p1 0 n))) n 0))
  37.     (MAT:vxv (MAT:v-v p2 p1) (MAT:v-v p3 p1))
  38.   )
  39. )
  40. ;;;向量差
  41. (defun MAT:v-v (v1 v2) (mapcar '- v1 v2))
  42. ;;;向量点积
  43. (defun MATDOT (v1 v2) (apply '+ (mapcar '* v1 v2)))
  44. ;;;向量叉积
  45. (defun MAT:vxv (u v)
  46.   (list        (- (* (cadr u) (caddr v)) (* (cadr v) (caddr u)))
  47.         (- (* (car v) (caddr u)) (* (car u) (caddr v)))
  48.         (- (* (car u) (cadr v)) (* (car v) (cadr u)))
  49.   )
  50. )
  51. (princ)






评分

参与人数 2明经币 +2 收起 理由
vectra + 1 看上去行
USER2128 + 1 赞一个!

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2017-10-23 09:58:28 | 显示全部楼层
  1. (setq A '(0 0 0)
  2.       B '(10 0 -7)
  3.       C '(5 10 15)
  4.       P '(5 5 3)
  5.       )

  6. (command "ucs" "")
  7. (command "ucs" a b c)
  8. (setq a1 (trans a 0 1))
  9. (setq b1 (trans b 0 1))
  10. (setq c1 (trans c 0 1))
  11. (setq p1 (trans p 0 1))
  12. (setq a1 (list (car a1) (cadr a1))
  13.       b1 (list (car b1) (cadr b1))
  14.       c1 (list (car c1) (cadr c1))
  15.       p1 (list (car p1) (cadr p1))
  16.       )
  17. (command "ucs" "")
  18. (command "pline" a1 b1 c1 "c")
  19. (setq plent (vlax-ename->vla-object (entlast)))
  20. (setq e0 (vla-get-Area plent))
  21. (vlax-put plent 'Coordinates (append a1 b1 p1))
  22. (setq e1 (vla-get-Area plent))
  23. (vlax-put plent 'Coordinates (append c1 b1 p1))
  24. (setq e2 (vla-get-Area plent))
  25. (vlax-put plent 'Coordinates (append a1 c1 p1))
  26. (setq e3 (vla-get-Area plent))
  27. (vla-delete plent)
  28. (command "ucs" "p")
  29. (command "ucs" "p")
  30. (command "ucs" "p")
  31. (>= 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
发表于 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表示在点上

  1. ;;重心法判别点是否在三角形内
  2. (defun PtInTriangle (p pa pb pc / DENO U V V0 V1 V2 VV00 VV01 VV02 VV11 VV12)
  3.   (setq v0 (MAT:v-v pc pa))
  4.   (setq v1 (MAT:v-v pb pa))
  5.   (setq v2 (MAT:v-v p pa))
  6.   (setq vv00 (MATDot v0 v0))
  7.   (setq vv01 (MATDot v0 v1))
  8.   (setq vv02 (MATDot v0 v2))
  9.   (setq vv11 (MATDot v1 v1))
  10.   (setq vv12 (MATDot v1 v2))
  11.   (setq deno (- (* vv00 vv11) (* vv01 vv01)))
  12.   (setq u (/ (- (* vv11 vv02) (* vv01 vv12)) deno 1.0))
  13.   (setq v (/ (- (* vv00 vv12) (* vv01 vv02)) deno 1.0))
  14.   (if (and (>= u 0) (>= v 0) (<= (+ u v) 1))
  15.     T
  16.     nil
  17.   )
  18. )


发表于 2017-10-21 08:55:57 | 显示全部楼层
回帖是一种美德!感谢楼主的无私分享 谢谢
发表于 2017-10-21 13:23:54 | 显示全部楼层
本帖最后由 xyp1964 于 2017-10-21 13:28 编辑

  1. (defun Mid2Pt (p1 p2)
  2.   (mapcar '(lambda (x y) (* (+ x y) 0.5)) p1 p2)
  3. )
  4. (defun abc (p a b c / pab pac pbc p1 p2 p3)
  5.   (setq  pab (Mid2Pt a b)
  6.   pac (Mid2Pt a c)
  7.   pbc (Mid2Pt c b)
  8.   p1  (Mid2Pt pab c)
  9.   p2  (Mid2Pt pac b)
  10.   p3  (Mid2Pt pbc a)
  11.   )
  12.   (and (<= (distance p p1) (distance p c))
  13.        (<= (distance p p1) (distance p pab))
  14.        (<= (distance p p2) (distance p b))
  15.        (<= (distance p p2) (distance p pac))
  16.        (<= (distance p p3) (distance p a))
  17.        (<= (distance p p3) (distance p pbc))
  18.   )
  19. )

  20. (setq a  '(0 0 0)
  21.       b  '(10 0 -7)
  22.       c  '(5 10 15)
  23.       p  '(5 5 3)
  24. )
  25. (abc p a b c)
发表于 2017-10-21 17:27:33 | 显示全部楼层
院长,这样判断不行,三星形内靠近端点的区域会出错

点评

给个实例  发表于 2017-10-21 23:35
发表于 2017-10-21 22:55:34 | 显示全部楼层
角APB,角BPC,角CPA,之和=360度时,P点在三角形内,小于360度时在三角形外。
发表于 2017-10-22 22:43:27 | 显示全部楼层
p与c距离小于p与p1,但p在三角形内

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2017-10-23 08:28:03 来自手机 | 显示全部楼层
不能坐标变换后再判断吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-9-29 21:24 , Processed in 0.181698 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表