假定在右手坐标系中的三角形3点坐标为A,B,C,判断P是否在ABC之内

( 主要来自 3D引擎研发QQ群(38224573 )的各位朋友的讨论 ,我仅仅算做个总结吧,特别感谢各位朋友的热情支持。 )

方法1:三个Perplane的方法

设AB,BC,AC边上的垂直平面为Perplane[3],垂直朝向内侧的法向为n[3]

1)先根据任意两边叉出法向N

N = AB.CrossProduct(AC);

N.Normalize();

D = A.DotProduct( N );

2)如果P在三角形所在平面之外,可直接判定不在平面之内( 假定方程为 ax+by+cz+d = 0 )

if( P.DotProduct( N ) + D > 0 ) return false;

3)然后法向和各边叉出垂直平面的法向

n[0] = N.CrossProduct(AB); //朝向内侧

n[0].Normalize();

Perplane[0].dist = A.DotProduct(n[0]);

Perplane[0].normal = n[0];

同样方法求得Perplane[1],Perlane[2];

3)因为三个Perplane都朝向三角形内侧,P在三角形内的条件是同时在三个Perplane前面;如果给定点P在任意一个垂直平面之后,那么可判定P在三角形外部

for( int i = 0;i<3;j++ )

{

if( P.DotProduct( Perplane[i].normal ) + Perplane[i].dist < 0 )

return false;

}

return true;//如果P没有在任意一条边的外面,可判断定在三角形之内,当然包括在边上的情况

方法2:三个部分面积与总面积相等的方法

S(PAB) + S(PAC) + S( PBC) = S(ABC) 则判定在三角形之内

用矢量代数方法计算三角形的面积为

S = 1/2*|a|*|b|*sin(theta)

= 1/2*|a|*|b|*sqrt(1-cos^2(theta))

= 1/2*|a|*|b|*sqrt(1- (a.DotProduct(b)/(|a|*|b|))^2);

另一种计算面积的方法是 S = 1/2*|a.CrossProduct(b)|

比较一下,发现后者的精确度和效率都高于前者,因为前者需要开方和求矢量长度,矢量长度相当于一次点乘,三个点乘加一个开方,显然不如

后者一次叉乘加一次矢量长度(注,一次叉乘计算相当于2次点乘,一次矢量长度计算相当于一次点乘),后者又对又快。

S(ABC)  = AB.CrossProduct(AC);//*0.5;

S(PAB)  = PA.CrossProduct(PB);//*0.5;

S(PBC)  = PB.CrossProduct(PC);//*0.5;

S(PAC)  = PC.CrossProduct(PA);//*0.5;

if( S(PAB) + S(PBC) + S(PAC) == S(ABC)  )

return true;

return false;

另一种计算三角形面积的矢量方法是 1/2*a.CrossProdcuct(b) ,CrossProduct = ( y1*z2 - y2*z1 , x1*z2 - x2*z1, x1*y2 - x2*z1 )

可以看到CrossProduct 的计算要比DotProduct多3个乘法计算,效率没有上面的方法高

方法3:三个向量归一化后相加为0

这个方法很怪异,发现自http://flipcode.spaces.live.com/blog/cns!8e578e7901a88369!903.entry 下面的一个回帖

如上图三角形ABC,P为AB外侧一点,N1,N2,N3 分别为BP,AP,CP的归一化矢量;NM为N1,N2夹角的角平分线

可以看出角A-P-B是三角形内角,必然小于180度,那么角N1-P-N2等于A-P-B;NM是N1-P-N2的角平分线,那么角B-P-N等于角N-P-A,而CPN必然小于其中一个,

即小于180/2 = 90度。结论是角N1,N2的合矢量方向与N3的夹角为锐角。所以N1,N2,N3的合向量模大于1.

这里注意,N3不一定在N1,N2之间,不能假定N2-P-N3 和N3-P-N1这两个角一定是锐角

同样可以推导出如果P在三角形内,N1+N2+N3必然小于0;若N1+N2+N3 = 0则P在三角形的边上。

有没有更简单的推导方法?

这个方法看起来很精巧,但是善于优化的朋友会立刻发现,三个矢量归一化,需要三个开方。迭代式开方太慢了,而快速开方有的时候又不满足精度要求。

方法4:重心坐标之和为1

{

BaryCenter = ( S(PAB)/S(PABC),S(PBC)/S(PABC),S(PAC)/S(PABC)) // 点P在三角形内的重心坐标

if( BaryCenter.x + BaryCenter.y + BaryCenter.z >0.f )

return false

return true;

}

其中S(PAB),S(ABC),S(PBC),S(PBC) 用上述的方法二种提到的计算三角形面积方法计算。

综合比较

方法1必须求叉乘,虽然可以通过首先排除不在平面内的点,但是后面仍要求三个叉乘和3个点乘(当然还可排除法优化)

方法2看起来之需要求4个点乘,如果用叉乘方法计算面积,可能会导致效率低下

方法3是看起来是最精巧的方法,但是效率也不能保证...3个开方

方法4和方法2的效率差不多

如何判断一点在三角形内相关推荐

  1. 射线与三角形求交,并判断是否在三角形内的完整代码(带测试)

    // Det.cpp : Defines the entry point for the console application. // #include "stdafx.h" # ...

  2. 几种方法判断平面点在三角形内

    最近在做一个Unity实现的3D建模软件,其中需要在模型表面进行操作的时候,需要用到点和三角形位置关系的判定算法.由于一个模型往往是几千个三角片,所以这个判定算法必须高效,否则会影响最终程序的整体性能 ...

  3. 阿里云天池超级码力在线编程大赛初赛 第2场 ABCD(A.计算几何 判断点在三角形内 D.大施罗德数/超级卡特兰数)

    心得 打了一下被群友吐槽的比赛,阅读体验极差 阴间题面,读题1小时,AC5min,原题警告 思路来源 https://blog.csdn.net/PleasantlY1/article/details ...

  4. [fzu 2273]判断两个三角形的位置关系

    首先判断是否相交,就是枚举3*3对边的相交关系. 如果不相交,判断包含还是相离,就是判断点在三角形内还是三角形外.两边各判断一次. //http://acm.fzu.edu.cn/problem.ph ...

  5. 海伦公式判断点和三角形的关系

    一 海伦公式 如果有一个三角形,它的三边分别为 $a, b ,c $, 则三角形的面积为 A=s(s−a)(s−b)(s−c)A = \sqrt{s(s-a)(s-b)(s-c)}A=s(s−a)(s ...

  6. 判断某一点是否在三角形内

    1.同向法 假设点P位于三角形内,会有这样一个规律,当我们沿着ABCA的方向在三条边上行走时,你会发现点P始终位于边AB,BC和CA的右侧.我们就利用这一点,但是如何判断一个点在线段的左侧还是右侧呢? ...

  7. 给定三角形ABC和一点P(x, y),判断P是否在三角形内

    解题思路: 根据点P与三角形其中两点所形成的三角形面积之和与三角形ABC面积进行比较,如果相等则点P在三角形内,不相等则不在三角形ABC内. 解题步骤: 一.根据给定的三点坐标计算三角形的面积: 二. ...

  8. 重心法-判断一点是否在三角形内

    1. 叉乘(X) 详细定义可以参考:叉积定义. 在三维坐标系中,如果 a = (a1, a2, a3), b = (b1, b2, b3),那么a x b = (a2b3 - a3b2, a3b1 - ...

  9. 判断点是否在三角形内

    本文只是翻译和整理,原文在此http://www.blackpawn.com/texts/pointinpoly/default.html 概述 给定三角形ABC和一点P(x,y,z),判断点P是否在 ...

最新文章

  1. 我从吴恩达 AI For Everyone 中学到的十个重要 AI 观
  2. Awk中调用shell命令
  3. 摘要:ASP.NET的路由
  4. java.awt.action 命令模式_java设计模式之命令模式
  5. OWIN的理解和实践(三) –Middleware开发入门
  6. 请简要说明一下CyclicBarrier和CountDownLatch的区别?
  7. C/C++混合编程——extern C
  8. python可以代替按键精灵吗_Python 假装自己是按键精灵
  9. 企业信息管理系统汇总
  10. 【JAVA】IOStream
  11. 小米蓝牙耳机使用说明_小米10手机专用?小米“真无线蓝牙耳机Air 2s”评测
  12. 数学建模系列--插值算法
  13. oracle的五种元素,五种元素
  14. HTML translate方法,HTML canvas translate()用法及代码示例
  15. 5操作系统的运行机制和体系结构
  16. 微信任务(投票)分发平台
  17. Android Surface 介绍
  18. 节气丨大雪至,人间至此雪盛时,岁暮天寒,顺问冬安
  19. PHP网站从服务器下载文件到本地
  20. XSS之xss-labs-level3

热门文章

  1. Acunetix WVS安装、破解+Web漏洞扫描
  2. 【转】国外SCI、EI检索期刊
  3. 浙江移动服务器维护升级时间,中国移动终于“良心了”!10年不换号的老用户,将获得这3大特权...
  4. 专家预言未来机器人性XX爱OO或成常态,并利于身心健康
  5. JS内置DATE对象部分函数对日期的支持只到1901年
  6. Ender的模拟赛D2T1 wait【min-max反演】
  7. java 正则最小匹配_正则表达式实现最小匹配功能的方法
  8. 机器视觉毕业设计 深度学习驾驶人脸疲劳检测系统 - python opencv
  9. 计算机视觉辅助系统价格,驾驶辅助系统计算机视觉技术
  10. 前端程序员需要了解的原生微信小程序-基础知识