Java 椭圆与直线相交

Java 椭圆与直线相交,java,geometry,line,intersection,ellipse,Java,Geometry,Line,Intersection,Ellipse,我有一个椭圆,有一个中点“mid”,一个水平半径“h”,一个垂直半径“v”,还有一条直线2d 现在我需要一些代码来计算两者的两个交点。 我已经试过一些代码,并且自己试过了,但是总是有错误 有人有工作代码吗?我会使用内置的ellipse和line/polygon类,它们都有确定碰撞和相交的方法你需要使用代数来解这两个方程,这会有点混乱。首先你必须写出椭圆 (1) (x/h)^2 + (y/v)^2 = 1 以及格式中的行 (2) y = ax + b 首先,在坐标轴上移动,使椭圆以原点为中心。

我有一个椭圆,有一个中点“mid”,一个水平半径“h”,一个垂直半径“v”,还有一条直线2d

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


有人有工作代码吗?

我会使用内置的ellipse和line/polygon类,它们都有确定碰撞和相交的方法

你需要使用代数来解这两个方程,这会有点混乱。首先你必须写出椭圆

(1) (x/h)^2 + (y/v)^2 = 1
以及格式中的行

(2) y = ax + b
首先,在坐标轴上移动,使椭圆以原点为中心。你可以通过从直线上减去中点来实现。计算交点后,通过添加中点将其移回

您可以从直线的起点和终点计算线性坡度,即δ-y/δ-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当直线由两点
P0
P1
给出时,直线上的任何点都是
(x,y)=(X0,Y0)+t(x1-X0,Y1-Y0)=(X0,Y0)+t(DX,DY)

椭圆是
(X-Xm)²/h²+(Y-Ym)²/v²=1

我们将使用一个技巧来简化计算:取所有
X
,减去
Xm
,然后除以
h
,得到
X
;取所有
Y
,减去
Ym
,然后除以
h
,得到
Y
。这将使椭圆变成以原点为中心的圆。(如果愿意,您可以在不减少坐标的情况下进行所有计算。)

现在,
(x,y)=(x0,y0)+t(dx,dy)
x²+y²=1

(tdx+x0)²+(tdy+y0)²=1

(dx²+dy²)t²+2(dx x0+dy y0)t+(x0²+y0²-1)=0


求解
t
的二次方程。如果有实根,您可以通过条件
0检查它们是否属于线段。我找不到提供此信息的方法。哪种方法是正确的?知道它们是否相交就足够了吗?你必须通过猜测来研究数学,因为你似乎将使用三角形。
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);
 }