LibGDX 线段与圆的交点坐标

LibGDX coordinates of intersection points between a Line Segment and a Circle

我正在使用 LibGDX 并且我有一条线段 (x1, y1, x2, y2) 与圆心 (cx, cy) 和半径 R 相交。

如何使用LibGDX(或纯Java)确定交点的坐标?

我检查了 Intersector.intersectSegmentCircle 方法,但是这个 return 只有 truefalse 没有 return交点坐标。

感谢您的帮助。

不是真正的答案,但对于评论和使用仅适用于答案的格式来说太长了。

要找到交点,在数学上,您需要求解两个联立方程。一个是圆,一个是直线。

您可以通过搜索互联网轻松找到这些方程式的形式。

  • 圆:(x - h)2 + (y - k)2 = r2
  • 行:y = mx + c

你可以找到一条直线的方程,给定直线上的两个点,你声称有两个这样的点。

您还声称拥有圆的所有数据,即圆心的坐标加上半径的长度。

然后您需要在 Internet 上搜索如何求解 java 中的联立方程。我发现了这个问题:

这是我的解决方案。

基本上是找到直线的一个参数方程,然后在圆的方程中代入各个坐标,我们用二次方程求解t。获得的值用于获取点坐标。请参阅答案 here 以获得更深入的数学解释。此外,由于在这种情况下直线不是无限长的,因此会检查所获得的交点是否适合直线所在的同一矩形。

我使用了你在图中使用的相同符号。

public class Intersections {

    /**
     * Returns a list of intersection points between the edge of a circle and a line.
     * @param cx Circle center X coordinate.
     * @param cy Circle center Y coordinate.
     * @param r Circle radius.
     * @param x1 First line X coordinate.
     * @param y1 First line Y coordinate.
     * @param x2 Second line X coordinate.
     * @param y2 Second line Y coordinate.
     * @return A list of intersection points.
     */
    public static List<Vector2> getCircleLineIntersectionPoints(
            float cx, float cy, float r, float x1, float y1, float x2, float y2) {
        // Find values to use in quadratic formula
        float dx = x2 - x1;
        float dy = y2 - y1;
        float a = dx * dx + dy * dy;
        float b = 2 * dx * (x1 - cx) + 2 * dy * (y1 - cy);
        float c = (float) Math.pow((x1 - cx), 2) + (float) Math.pow((y1 - cy), 2) - r * r;
        float d = b * b - 4 * a * c;  // Discriminant

        ArrayList<Vector2> points = new ArrayList<>();
        if (d >= 0) {
            // Perform quadratic formula to get 2 points
            float root = (float) Math.sqrt(d);
            float t1 = 2 * c / (-b + root);
            float t2 = 2 * c / (-b - root);

            // Need the rectangle bounds that the line fits in to check
            // if intersection points are within the line bounds
            float xmin = Math.min(x1, x2);
            float ymin = Math.min(y1, y2);
            float xmax = Math.max(x1, x2);
            float ymax = Math.max(y1, y2);

            // Add first point
            float p1x = x1 + dx * t1;
            float p1y = y1 + dy * t1;
            if (isPointInRectangle(xmin, ymin, xmax, ymax, p1x, p1y)) {
                points.add(new Vector2(p1x, p1y));
            }

            // Add second point if there's one
            if (!MathUtils.isEqual(t1, t2)) {
                float p2x = x1 + dx * t2;
                float p2y = y1 + dy * t2;
                if (isPointInRectangle(xmin, ymin, xmax, ymax, p2x, p2y)) {
                    points.add(new Vector2(p2x, p2y));
                }
            }
        }
        return points;
    }

    private static boolean isPointInRectangle(
            float xmin, float ymin, float xmax, float ymax, float px, float py) {
        return px >= xmin && py >= ymin && px <= xmax && py <= ymax;
    }
}

请注意,如果两个线点相同但位于圆的边缘,则此操作失败并且 returns 没有点。我没有对其进行太多测试,因此请确保它适用于您的所有情况。

编辑:可以检查 t 值是否在 0 和 1 之间,而不是检查点是否在矩形中。但是 x1y1x2y2 需要替换为 xminyminxmaxymax