【问题标题】:LibGDX coordinates of intersection points between a Line Segment and a Circle线段和圆之间交点的 LibGDX 坐标
【发布时间】:2020-02-20 03:47:45
【问题描述】:

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

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

我检查了 Intersector.intersectSegmentCircle 方法,但这仅返回 truefalse 而不返回交点坐标。

感谢您的帮助。

【问题讨论】:

    标签: java libgdx


    【解决方案1】:

    这是我的解决方案。

    基本上找到了直线的参数方程,然后将每个坐标替换在圆的方程中,我们使用二次公式求解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;
        }
    }
    

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

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

    【讨论】:

      【解决方案2】:

      对于评论并使用仅适用于答案的格式,还不是真正的答案。

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

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

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

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

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

      然后您需要在 Internet 上搜索如何在 java 中求解联立方程。我发现了这个 SO 问题:
      How to solve a 2 variable linear simultaneous equation? Java

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-27
        • 2013-04-25
        • 2011-09-26
        • 2019-06-06
        相关资源
        最近更新 更多