【问题标题】:LIBGDX Where does a Polygon and a Line collide?LIBGDX 多边形和线在哪里碰撞?
【发布时间】:2016-03-03 20:02:31
【问题描述】:

我想得到多边形和线碰撞的点。我知道有一个名为 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;
}

【问题讨论】:

  • 请提供一些代码。这里有两个选择:1)你解决了没有 libGDX 上下文的线和形状相交的问题 2)你很高兴使用集成的 box2d 支持
  • 抱歉,您想要碰撞的全局位置(例如:x,y 处的碰撞)?或者你想知道你的线在哪里接触你的多边形和/或这个多边形在哪里接触线(比如:我的线头接触我的多边形的左侧)?
  • 我使用了一个矩形碰撞系统,效果非常好,但现在我将整个代码更改为多边形碰撞系统,这会带来一些主要问题,比如“Ray追踪”

标签: java libgdx line polygon


【解决方案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 的线段与多边形边缘的交点。 (特别是,它正在确定给定线segments 之间是否有任何相交,这在后面很重要。)特别是,正在对这两个线段的参数方程进行计算;例如,从 (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) 来计算交点的坐标。因此,要找到交点,您可以创建自己的返回值的函数版本

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

希望这会有所帮助!

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我知道这种情况经常发生,但在那个特定的方法上没有一个
    • 这是你使用的方法public static boolean intersectLinePolygon (Vector2 p1, Vector2 p2, Polygon polygon) 吗?
    • 您可以修改intersectLinePolygon的现有代码或使用intersectLines迭代多边形的每一边,返回Vector2 intersection
    • 如果您选择实施 Leo 的建议,请使用 intersectSegments 而不是 intersectLines
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多