LIBGDX多边形和一条线在哪里发生碰撞?

时间:2016-03-03 20:02:31

标签: java libgdx line polygon

我想要获得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;
}

2 个答案:

答案 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。

我从来没有使用过这个图书馆,但乍一看,这就是它的工作方式。