Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 保证多边形法线的向外方向_Java_Vector_Geometry - Fatal编程技术网

Java 保证多边形法线的向外方向

Java 保证多边形法线的向外方向,java,vector,geometry,Java,Vector,Geometry,我试图用Java编写一个2D游戏,使用分离轴定理进行碰撞检测。为了解决两个多边形之间的碰撞,我需要知道碰撞的最小平移向量,并且我需要知道它相对于多边形指向哪个方向(这样我可以给一个多边形一个沿该方向的惩罚力,给另一个多边形一个沿相反方向的惩罚力)。作为参考,我正在尝试实现该算法 我想保证,如果调用我的碰撞检测函数collide(Polygon polygon1,Polygon polygon2)并检测到碰撞,返回的MTV将始终指向polygon1,指向polygon2。为此,我需要确保生成的分离

我试图用Java编写一个2D游戏,使用分离轴定理进行碰撞检测。为了解决两个多边形之间的碰撞,我需要知道碰撞的最小平移向量,并且我需要知道它相对于多边形指向哪个方向(这样我可以给一个多边形一个沿该方向的惩罚力,给另一个多边形一个沿相反方向的惩罚力)。作为参考,我正在尝试实现该算法

我想保证,如果调用我的碰撞检测函数
collide(Polygon polygon1,Polygon polygon2)
并检测到碰撞,返回的MTV将始终指向polygon1,指向polygon2。为此,我需要确保生成的分离轴(即多边形边的法线)始终指向生成它们的多边形。(这样,我知道在将polygon2用作MTV之前,要否定它的任何轴)

不幸的是,我为多边形边生成的法线是否指向多边形的内部或外部取决于多边形的点是按顺时针还是逆时针顺序声明的。我正在使用描述的算法生成法线,假设我为“垂直”方法选择
(x,y)=>(y,-x)
,如果我按顺时针顺序迭代顶点,生成的法线将仅指向远离多边形的方向


考虑到我不能强制客户端按顺时针顺序声明多边形的点(我使用的是java.awt.polygon,它只公开了x和y坐标的两个数组),有没有数学方法来保证我生成的法向量的方向朝向多边形的外部?我不太擅长向量数学,所以可能有一个明显的解决方案,我没有。大多数关于SAT的互联网资源都假设你总是可以按顺时针顺序迭代多边形的顶点。

你可以使用问题的答案计算每个多边形的顺序,然后如果两个多边形的顺序不同,将法线乘以-1

您还可以检查传递给算法的每个多边形,查看其顺序是否不正确,再次使用上述算法,并在必要时反转顶点顺序


请注意,在计算顶点顺序时,有些算法适用于所有多边形,有些算法仅适用于凸多边形。

我终于找到了答案,但给出的答案不是完整的解决方案,因此我不打算接受它。我能够使用中描述的基本算法(也在David Norman的链接中描述得不太清楚)确定多边形的顺序,即:

for each edge in polygon:
    sum += (x2 - x1) * (y2 + y1)
然而,这些答案都没有提到一个重要的警告。通常,如果该和为正,则可以确定多边形的顶点为顺时针方向,如果该和为负,则可以确定多边形的顶点为逆时针方向。但是在Java的2D图形系统中,实际上在许多图形系统中,比较是相反的,因为正y轴指向下方。在正常的数学坐标系中,你可以说

if sum > 0 then polygon is clockwise
但在一个y轴倒置的图形坐标系中,它实际上是

if sum < 0 then polygon is clockwise
如果和<0,则多边形为顺时针方向
我的实际代码使用Java的多边形,如下所示:

//First, find the normals as if the polygon was clockwise

int sum = 0;
for(int i = 0; i < polygon.npoints; i++) {
    int nextI = (i + 1 == polygon.npoints ? 0 : i + 1);
    sum += (polygon.xpoints[nextI] - polygon.xpoints[i]) * 
        (polygon.ypoints[nextI] + polygon.ypoints[i]);
}

if(sum > 0) {
    //reverse all the normals (multiply them by -1)
}
//首先,像多边形是顺时针方向一样查找法线
整数和=0;
对于(int i=0;i0){
//反转所有法线(将其乘以-1)
}