我想要获得Polygon和Line碰撞的Point。我知道有一个名为Intersector的类,但是在这里只有一种检查它们是否发生碰撞的方法,但是我需要它们碰撞的点。
我很满意任何帮助
public static List<RayTrace> rayTrace(Line2D line, boolean quick, Collisions... collisions) {
List<RayTrace> l = new ArrayList<RayTrace>();
for (Collisions collisions1 : collisions) {
for (Collision3D collision3D : collisions1) {
RayTrace rayTrace = new RayTrace();
if (quick) {
if (Intersector.intersectLinePolygon(line.getStartV(), line.getEndV(), collision3D.getBoundingPolygon())) {
rayTrace.collisionHit = collision3D;
rayTrace.hasHit = true;
l.add(rayTrace);
}
} else {
Point2f hit = new Point2f();
if (CollisionHelper.getLinePolygonIntersection(collision3D.getBoundingPolygon(), line, hit)) {
rayTrace.collisionHit = collision3D;
rayTrace.hasHit = true;
rayTrace.hitX = hit.x;
rayTrace.hitZ = hit.y;
l.add(rayTrace);
}
}
}
}
return l;
}
public static List<Vector2> getLinePolygonIntersections(Polygon polygon, Line2D line) {
float f[] = polygon.getTransformedVertices();
//Go through every side
List<Vector2> intersections = new ArrayList<Vector2>();
for (int i = 0; i < f.length - 2; i += 2) {
Vector2 intersection = new Vector2();
Intersector.intersectLines(line.x, line.y, line.x2, line.y2, f[i], f[i + 1], f[i + 2], f[i + 3], intersection);
intersections.add(intersection);
}
return intersections;
}
public static boolean getLinePolygonIntersection(@NotNull Polygon polygon, @NotNull Line2D line, @NotNull Point2f point) {
List<Vector2> list = getLinePolygonIntersections(polygon, line);
if (list.size() == 0) return false;
double shortestDistance = line.getStart().distance(new Point2f(list.get(0).x, list.get(0).y));
int indexClosest = 0;
for (int i = 1; i < list.size(); i++) {
double d = new Point2f(list.get(i).x, list.get(i).y).distance(line.getStart());
if (shortestDistance > d) {
indexClosest = i;
shortestDistance = d;
}
}
point.set(list.get(indexClosest).x, list.get(indexClosest).y);
return true;
}
答案 0 :(得分:1)
以下是LibGDX Intersector类中可以修改的方法:
public static boolean intersectLinePolygon (Vector2 p1, Vector2 p2, Polygon polygon) {
float[] vertices = polygon.getTransformedVertices();
float x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y;
int n = vertices.length;
float x3 = vertices[n - 2], y3 = vertices[n - 1];
for (int i = 0; i < n; i += 2) {
float x4 = vertices[i], y4 = vertices[i + 1];
float d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
if (d != 0) {
float yd = y1 - y3;
float xd = x1 - x3;
float ua = ((x4 - x3) * yd - (y4 - y3) * xd) / d;
if (ua >= 0 && ua <= 1) {
return true;
}
}
x3 = x4;
y3 = y4;
}
return false;
}
这个方法实际上在做的是找到p1到p2的线段与多边形边缘之间的交点。 (特别是,它确定给定的行段之间是否存在任何交叉,这在以后将是重要的。)特别是,正在对这两个线段的参数方程执行计算;例如,从(x1,y1)到(x2,y2)的段行具有参数方程
L(t) = [ x2-x1, y2-y1 ] * t + [ x1, y1 ]
其中t
的范围是0到1.
使用Cramer规则计算线的交点;上面的变量d
表示出现在该公式的分母中的矩阵的行列式。当d
非零时,保证线之间有交点,但我们还没有完成,因为我们对线段的交叉感兴趣。当交叉发生时,方法中的变量ua
在上面的参数方程中产生t
的值;如果交点位于线段的端点之间,则它必须介于0和1之间。
因此,可以通过在L(t)
时评估t = ua
来计算交点的坐标。因此,要找到交点,您可以创建自己的此函数版本,该函数返回值
Vector2( (x2-x1)*ua + x1, (y2-y1)*ua + y1)
希望这有帮助!
答案 1 :(得分:0)
恕我直言:在Intersector类中,许多方法计算碰撞,通常最后一个参数是一个填充了碰撞坐标的Vector3。
我从来没有使用过这个图书馆,但乍一看,这就是它的工作方式。