二维三角形-正方形相交测试
Triangle - Square intersection test in 2d
如何测试三角形和正方形是否相交?
当我们知道它是正方形而不是矩形时,有什么方法可以优化它吗?此外,正方形是轴对齐的,这应该会给性能带来更多的提升吗?
还是我应该把正方形分成三角形,然后进行两次三角交叉检查?
编辑:澄清:我正在尝试检查这两个形状是否以任何方式重叠。三角形可以在正方形里面,正方形可以在三角形里面,它也应该返回true。
将矩形(或正方形)与三角形的每条边进行比较,方法是取三角形的顶点,并为每条边建立一条直线方程,顺序一致(围绕三角形顺时针或逆时针)。
如果矩形完全在三角形的任何边上,则它不相交。
将矩形的边缘与三角形进行再次测试。
知道矩形是轴对齐的,可能会提高性能,因为你可以计算出哪个角最有可能在三角形内,只测试那个角,而不是测试所有四个角。
这是否是一场胜利取决于执行情况。有时,盲目检查四个坐标比实际计算最佳坐标更快。
根据矩形检查三角形应该更容易,因为当矩形轴对齐时,线性方程是针对x或y的简单测试。
这是分离轴测试的一种通用形式——找到一条将两个物体分离的线或平面,从而证明它们不能相交。如果想要更高的性能,可以找到两个对象中最接近的特征,以确定最合适的线/平面,而不是尝试所有这些特征。
这是一个经典的碰撞检测问题。如果以下任何条件成立,则形状相交:
- 三角形中至少有一个顶点包含在矩形中
- 矩形的至少一个顶点包含在三角形中
- 三角形的任意边与矩形的任意边相交
前两个条件涵盖了其中一个形状与另一个形状完全包含的可能性(在这种情况下,边不会相交)。
一些优化是可能的。
-
计算形状的外接圆。如果两个形状的中心点之间的距离大于外接圆的半径之和,则可以排除碰撞。请注意,外接矩形的圆的圆心是其对角线的中点。三角形的外切圆的中心点可以通过求任意两条边的垂直平分线的交点来获得。找到完全包含三角形的悲观估计圆的两种方法是:(1)使用最长的边作为圆的直径,以及(2)创建一个边角位于(mintx,minity),(mintx,maxtyaxtx,maxty)和(max tx,mintyem>max tx[/em>是任何三角形角的最大X坐标,mintx是任何三角角的最小X坐标,等等。
-
可以平移和旋转形状,使矩形的一个顶点位于原点,矩形的底部沿正X轴。这使得查找三角形中的顶点是否包含在矩形中变得简单。
平移、旋转和线交叉都是众所周知的问题,在stackoverflow、stackoverflow或web上的其他地方找到合适的代码应该不会有问题。
提示:
- 平移很简单--在每个X或Y坐标上添加或减去相同的值
-
从概念上讲,旋转很容易——对于每个点,转换为极坐标,添加或减去旋转角度,然后转换回笛卡尔坐标。由于转换到极坐标/从极坐标转换极坐标在计算上很昂贵,因此可以使用以下公式进行旋转:
Xrot=X*cos(θ)-Y*sin(θ)
Yrot=X*sin(theta)+Y*cos(theta -
你可以通过取矩形的一边来找到角度theta,并注意到
θ=atan2(deltaX,deltaY)
作为对Jay Elston答案的改进,您可以将正方形/四边形拆分为两个三角形,然后使用Möller–Trumbore交集算法来比较顶点的包含情况。如果你阅读了发表的论文,最后有一个C实现的算法。
这样可以检查是否包含顶点。然后使用周的一个链接进行交叉。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 试试完美的正方形,你能给点小费吗
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 尽管测试成功,CppUnit测试核心仍被丢弃.为什么
- 数据成员SFINAE的C++17测试:gcc vs clang
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么二进制搜索在我的测试中不起作用
- 从父数组测试用例构造二叉树失败
- 试图对缓存进行跨步测试,但程序并没有结束
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- OpenGL在启用深度测试时不会丢弃我的碎片
- 为测试目标创建具有不同源文件夹的文件
- 在子目录中使用target_sources()命令时用于单元测试(qtest)的项目结构
- VC++本机单元测试,找不到调试符号
- 换位表导致测试失败(但在游戏中运行良好)
- 用于交叉编译和CMake的预处理器宏的单元测试
- 谷歌测试中的期望值存储在哪里
- 如何在for循环中包含两个索引值的测试条件
- 在cygwin中测试新的boost安装时出现cpp错误
- 二维三角形-正方形相交测试