Ivo*_*zel 5 java polygon collision-detection
好的,所以我试图制作一个简单的小行星克隆.除碰撞检测外,一切正常.
我有两个不同的版本,第一个使用java.awt.geom.Area:
// polygon is a java.awt.Polygon and p is the other one
final Area intersect = new Area();
intersect.add(new Area(polygon));
intersect.intersect(new Area(p.polygon));
return !intersect.isEmpty();
Run Code Online (Sandbox Code Playgroud)
这就像一个魅力......如果你不关心只有120个小行星的40%CPU :(
所以我在网上搜索了着名的分离轴定理,因为我不是很好的数学,我从这里开始实现并转换它以满足我的Java需求:
public double dotProduct(double x, double y, double dx, double dy) {
return x * dx + y * dy;
}
public double IntervalDistance(double minA, double maxA, double minB,
double maxB) {
if (minA < minB) {
return minB - maxA;
} else {
return minA - maxB;
}
}
public double[] ProjectPolygon(double ax, double ay, int p, int[] x, int[] y) {
double dotProduct = dotProduct(ax, ay, x[0], y[0]);
double min = dotProduct;
double max = dotProduct;
for (int i = 0; i < p; i++) {
dotProduct = dotProduct(x[i], y[i], ax, ay);
if (dotProduct < min) {
min = dotProduct;
} else if (dotProduct > max) {
max = dotProduct;
}
}
return new double[] { min, max };
}
public boolean PolygonCollision(Asteroid ast) {
int edgeCountA = points;
int edgeCountB = ast.points;
double edgeX;
double edgeY;
for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++) {
if (edgeIndex < edgeCountA) {
edgeX = xp[edgeIndex] * 0.9;
edgeY = yp[edgeIndex] * 0.9;
} else {
edgeX = ast.xp[edgeIndex - edgeCountA] * 0.9;
edgeY = ast.yp[edgeIndex - edgeCountA] * 0.9;
}
final double x = -edgeY;
final double y = edgeX;
final double len = Math.sqrt(x * x + y * y);
final double axisX = x / len;
final double axisY = y / len;
final double[] minMaxA = ProjectPolygon(axisX, axisY, points, xp,
yp);
final double[] minMaxB = ProjectPolygon(axisX, axisY, ast.points,
ast.xp, ast.yp);
if (IntervalDistance(minMaxA[0], minMaxA[1], minMaxB[0], minMaxB[1]) > 0) {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
它有效......有点儿.实际上,当使用这个代码时,小行星的"碰撞船体"似乎太大了,它就像是小行星大小的1.2倍.而且我没有任何线索为什么.
这是两张图片供比较:
http://www.spielecast.de/stuff/asteroids1.png
http://www.spielecast.de/stuff/asteroids2.png
正如你可以看到的那样,图片1中的小行星比使用SAT代码的图2中的小行星更密集.
那么任何想法?或者有没有人知道我可以使用的具有相交测试的Java的Polygon实现?
看起来您的第二个结果是进行碰撞检测,就好像多边形是圆形,其半径设置为多边形距中心最远的点。我见过的大多数碰撞检测工具都会创建一个简单的边界框(圆形或矩形),多边形可以放入其中。仅当两个边界框相交(计算更简单)时,您才继续进行更详细的检测。也许适当的算法仅用作边界框计算器?
编辑:另外,来自维基百科
如果其中一个物体不是凸的,则该定理不适用。
图像中的许多小行星都有凹面。
| 归档时间: |
|
| 查看次数: |
1176 次 |
| 最近记录: |