LIBGDX多边形和直线在哪里碰撞?

LIBGDX Where does a Polygon and a Line collide?

我想获取多边形和直线相交的点。我知道有一个叫做 Intersector 的class,但是这里只有一个方法来检查它们是否碰撞,但我需要它们碰撞的点。

我很高兴得到任何帮助

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;
}

恕我直言:在 Intersector class 中,许多方法计算碰撞,通常最后一个参数是填充碰撞坐标的 Vector3。

我从未使用过这个库,但乍一看,它就是这样工作的。

这是来自 LibGDX Intersector class 的可以修改的方法:

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) 的 segment 线具有参数方程

L(t) = [ x2-x1, y2-y1 ] * t + [ x1, y1 ] 

其中 t 的范围从 0 到 1。

直线的交点是使用克拉默法则计算的;上面的变量 d 表示出现在该公式的分母中的矩阵的行列式。当 d 不为零时,保证线之间有交点,但我们还没有完成,因为我们对线段的交点感兴趣。当相交发生时,方法中的变量 ua 产生上述参数方程中 t 的值;对于位于线段端点之间的交点,它必须介于 0 和 1 之间。

因此,当t = ua时,可以通过计算L(t)来计算交点的坐标。因此,要找到交点,您可以创建自己的此函数版本,returns 值

Vector2( (x2-x1)*ua + x1, (y2-y1)*ua + y1)

希望对您有所帮助!