java - 椭圆与直线相交JAVA

标签 java geometry line intersection ellipse

我有一个椭圆,其中点为“mid”,水平半径为“h”,垂直半径为“v”,还有一个 Line2D。

现在我需要一些代码来计算两者的两个交点。 我已经尝试过一些代码并自己尝试过,但总是有错误。

有人有一些工作代码吗?

最佳答案

您需要使用代数来求解这两个方程,这会变得有点困惑。首先你必须写出椭圆

(1) (x/h)^2 + (y/v)^2 = 1

以及格式中的行

(2) y = ax + b

首先,在坐标轴上移动,使椭圆以原点为中心。您可以通过从直线中减去 mid 来做到这一点。计算出交点后,通过添加中点将它们向后移动。

您可以从直线的起点和终点计算 delta-y/delta-x 的线性斜率。您必须检查斜坡是否垂直。如果斜率是垂直的,您只需检查线点的 x 值是否落在椭圆的位置,然后轻松计算值。把它画在纸上,看看如何计算。

现在假设斜坡不是垂直的。由于您通过直线知道了 y 的 x 值,因此将其平方并代入 (1)。化简得到二次方程。

(3) ((ah)^2+v^2)x^2 + (2abh^2)x + ((hb)^2-(hv)^2) = 0

使用二次公式给出交点 x 坐标的两个值。如果 x 有两个实值,则有两个交集。如果 x 只有一个实数解,则存在一个交集。如果 x 没有实数解,则不存在交集。

给定 ax^2 + bx + c = 0, x 由下式给出

x = (1/2a)(-b +- Sqrt(b^2 - 4ac))

设 D = b^2 - 4ac

如果 D < 0,则没有交集

如果 D = 0,则有一个交集

如果 D > 0,则有两个交点

计算出 x 交点的值后,将 x 的值代入 (2) 以获得 y 值。

现在,您需要确保这些点落在直线内。为此,只需检查计算点的 x 和 y 分量是否满足 x1 <= x <= x2 和 y1 <= y <= y2,其中 x1 是线的最小 x 端点,x2 是线的最大 x 端点,y1是线的最小 y 端点,y2 是最大的 y 端点。

这是我制作的示例方法

public static ArrayList<Point2D> getIntersection(double x1, double x2, double y1, double y2, double midX, double midY, double h, double v) {
     ArrayList<Point2D> points = new ArrayList();

     x1 -= midX;
     y1 -= midY;

     x2 -= midX;
     y2 -= midY;

     if (x1 == x2) { 
         double y = (v/h)*Math.sqrt(h*h-x1*x1);
         if (Math.min(y1, y2) <= y && y <= Math.max(y1, y2)) {
             points.add(new Point2D(x1+midX, y+midY);
         }
         if (Math.min(y1, y2) <= -y && -y <= Math.max(y1, y2)) {
             points.add(newPoint2D(x1+midX, -y+midY);
         }
     }
     else {
         double a = (y2 - y1) / (x2 - x1);
         double b = (y1 - a*x1);

         double r = a*a*h*h + v*v;
         double s = 2*a*b*h*h;
         double t = h*h*b*b - h*h*v*v;

         double d = s*s - 4*r*t;

         if (d > 0) {
             double xi1 = (-s+Math.sqrt(d))/(2*r);
             double xi2 = (-s-Math.sqrt(d))/(2*r);

             double yi1 = a*xi1+b;
             double yi2 = a*xi2+b;

             if (isPointInLine(x1, x2, y1, y2, xi1, yi1)) {
                 points.add(new Point2D.Double(xi1+midX, yi1+midY);
             }
             if (isPointInLine(x1, x2, y1, y2, xi2, yi2)) {
                 points.add(new Point2D.Double(xi2+midX, yi2+midY);
             }
         }
         else if (d == 0) {
             double xi = -s/(2*r);
             double yi = a*xi+b;

             if (isPointInLine(x1, x2, y1, y2, xi, yi)) {
                 points.add(new Point2D.Double(xi+midX, yi+midY));
             }
         }
     }

     return points;
 }

 public static boolean isPointInLine(double x1, double x2, double y1, double y2, double px, double py) {
     double xMin = Math.min(x1, x2);
     double xMax = Math.max(x1, x2);

     double yMin = Math.min(y1, y2);
     double yMax = Math.max(y1, y2);

     return (xMin <= px && px <= xMax) && (yMin <= py && py <= yMax);
 }

请随意检查我的代数和代码,但您应该通过仔细完成每个代数步骤来解决这个问题。

关于java - 椭圆与直线相交JAVA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24164485/

相关文章:

java - 确定一个弧是否包含/覆盖另一个弧

java - Eclipse JFrame 警告

java - vector 中的 vector ... Java

java - 9-patch 文件中出现奇怪的黑边 - android

algorithm - 为 delaunay 三角剖分实现 Bowyer-Watson 算法

r - 将 lines() 应用于数据框/矩阵的列;每条线都有不同的颜色

java - 如何检测客户端机器是否已经安装了JRE版本?

unity3d - 寻找线段-矩形交点

arrays - 如何通过powershell将文本文件的每一行保存为数组

c++ - 如何在 C++ 程序中获取错误行号