C 在2D中,如何确定三角形和AABB是否相交

C 在2D中,如何确定三角形和AABB是否相交,c,algorithm,2d,intersection,aabb,C,Algorithm,2d,Intersection,Aabb,我正在为一个定制的末日引擎编写一个物理引擎 我的目标不是复制最初厄运的确切行为 在厄运中,每个“东西”(玩家、怪物等)都是一个轴对齐的边界框。我想留着它 我已经有了一个适用于扇区的有效细分算法 我已经有了一个工作的四叉树,使用了扇形三角形的AABB盒 四叉树将返回与给定AABB(例如,播放器)相交的候选列表 我想要的是:一个算法来测试一个三角形是否在2D中与一个AABB相交 我能做的是:将AABB分割成两个三角形,然后进行三角形相交检查。 我能做的是:使用“三角形vs aabb”算法处理3D,并

我正在为一个定制的末日引擎编写一个物理引擎

我的目标不是复制最初厄运的确切行为

在厄运中,每个“东西”(玩家、怪物等)都是一个轴对齐的边界框。我想留着它

我已经有了一个适用于扇区的有效细分算法

我已经有了一个工作的四叉树,使用了扇形三角形的AABB盒

四叉树将返回与给定AABB(例如,播放器)相交的候选列表

我想要的是:一个算法来测试一个三角形是否在2D中与一个AABB相交

我能做的是:将AABB分割成两个三角形,然后进行三角形相交检查。 我能做的是:使用“三角形vs aabb”算法处理3D,并将“z”设置为0。 我能做的是:

1/检查三角形的一点是否在AABB内

2/检查AABB的中心是否在三角形内(为了避免圆角问题,中心是更好的候选者)

3/检查三角形的线段是否与AABB的线段相交

我不想这样做,因为:我认为,鉴于这种精确的情况,应该有一种更优化的方法来做到这一点。 这正是GPU必须经常面对的问题:查找视口中是否有三角形。我认为这个问题,比任何其他问题都更重要的是,已经被解决到了地狱

请注意,情况可能更简单:我可以翻译所有内容,以便AABB从(0,O)开始。我可以调整所有内容的大小,使问题变成: “如何确定三角形是否与[0,1][0,1]相交。”

我已经做了一些研究,但是:

1/大多数结果都是针对3D内容的

奇怪的是,这是一个不常涉及的案例。甚至在《游戏物理食谱》一书中也没有提到这个问题

3/我找到的答案很难,很一般,有SAT(分离轴定理)或类似的东西

对于四叉树给出的每个候选三角形,我必须对很多“东西”(玩家、怪物)进行每帧测试

我还有最后一个选择,但我真的不知道从哪里开始,甚至不知道这是否是个好主意。这里是我脑海中的一个快速总结

1/因为gpu已经有了所有这些三角形

2/因为它是大规模并行的

3/如果超过了固定成本,则不会有额外成本

=>询问gpu

但我不知道怎么做。通信cpu/gpu将有成本,但成本是固定的(1件或10万件的成本大致相同)。 我宁愿避免这种解决方案(但当网站要求我说出我的想法时,我正在谈论它)

请注意,这是我在这个网站上的第一条信息。 请注意英语不是我的母语。 请注意,现在是凌晨3:32(晚上)。 请注意,我将无法在明天大约同一时间回答(事实上,每天都是如此)


感谢阅读,提前感谢您的回答。

以下是我的尝试。原则上,您可以始终测试线段交点,但如果您想保存浮点运算,在某些情况下您可以选择快捷方式。AABB将平面划分为九个区域(左上、左上、右上、左内、右下、左下、右下)。如果您只查看三角形的点所在的区域,就可以确定相交必须发生还是不发生。然而,有些情况无法在此基础上作出决定,因此有必要回到几何相交。这是我的代码,我认为它是正确的(如中所示,所有基于区域的测试都定义得很好),尽管我没有进行彻底的测试。它相当长,但大部分是按位操作,因此实际上应该相当快。入口点是函数<代码>相交<代码>,主函数中有一个示例

#包括
#包括
#定义ε1e-6
类型定义结构AABB{
浮点数x0,y0,x1,y1;
}AABB;
类型定义结构点{
浮动x,y,z;
}点;
typedef结构三角形{
点p1、p2、p3;
}三角形;
//命名假定(0,0)位于左上角
typedef枚举区域{
左上角=1 aabb->x1){
如果(点->yy0){
返回右上角;
}否则如果(点->y>aabb->y1){
返回右下角;
}否则{
返还权;
}
}否则{
如果(点->yy0){
返回顶部;
}否则如果(点->y>aabb->y1){
返回底部;
}否则{
返回内部;
}
}
}
//1:有十字路口
//0:可能有交叉点,也可能没有交叉点
整数区域相交(区域r1,区域r2){
如果(((r1 | r2)和内部)!=0)||
((r1 | r2)==(左|右))||
((r1 | r2)==(顶部|底部))){
返回1;
}否则{
返回0;
}
}
//1:有十字路口
//0:可能有交叉点,也可能没有交叉点
//-1:没有交叉口
//不检查区域_intersect_2已覆盖的案例
int区域_相交_3(区域r1、区域r2、区域r3){
区域r23=r2 | r3;
开关(r1){
案例左上角:
如果(r23==(右下)||
r23==(底部|顶部|右侧)||
r23==(右|下(左))){
返回1;
}如果((r23&(左上|左|左下|))==r23||
(r23&(左上|右上|右上))==r23){
返回-1;
}
案例顶部:
如果(r23==(左|下|右)||
r23==(右|下(左))){
返回1;
}else if((r23&(左上|右上|右上))==r23){
返回-1;
}
案例右上角:
如果(r23==(左下)||
r23==(底部|顶部|左侧)||
r23==(左)