如何找到椭圆和直线之间的交点?

时间:2012-05-21 19:58:37

标签: java geometry coordinates

我完全卡住了。 我有一个椭圆和一条线。线由两个点设置,椭圆 - 左下角和右上角。我必须使用java找到他们的交点。 我试图解决方程式系统:

(1) y = kx + m;
x^2/a^2 + y^2/b^2 = 1;

但我无法使事情正常运作。我认为这是因为java的坐标系统,但它也可能是我自己的错误,因为我很困惑。

有没有更好的方法来找到交叉点,如果没有,我怎样才能正确找到它们?

提前谢谢。

代码:

double r1 = in_y2-in_y;
double r2 = in_x2-in_x;
double k = r1/r2;
double m = in_y2 - k*in_x2;
double a =  Math.abs((double)x2 - (double)x)/2;
double b =  Math.abs((double)y2 - (double)y)/2;

double A1 = 1/(a*a) + (k*k)/(b*b);
double B1 = (2*k*m)/b*b;
double C1 = (m*m)/(b*b);
double D = Math.sqrt(B1*B1 - 4*A1*C1);
double ex1 = (-B1 + D/(2*A1));
double ey1 = k*ex1 + m;
double ex2 = (-B1 - D/(2*A1));
double ey2 = k*ex2 + m;

4 个答案:

答案 0 :(得分:2)

Java无法解决代数问题,但是一旦你告诉它要计算什么,它就可以计算解决方案。

听起来你需要用y替换椭圆方程中的kx+m然后求解x。看起来这是一个简单的二项式方程。编写一个基于k,m,a和b计算x=...的程序。如果你告诉它计算什么以及k,m,a和b的值是什么,Java可以帮助你计算根。

在您的特定情况下,您希望将Java用作简单的计算器......

答案 1 :(得分:2)

这可能与原始问题所有者不再相关,但由于我遇到了同样的问题,让我提出我的答案。

我可以看到原始计算中有三个错误:(i)@mprivat指出的错误,(ii)B1指派中的包围,而应该是

double B1 = (2*k*m)/(b*b);

和(iii)更基本的一个:所呈现的计算不能校正椭圆的原点。由于椭圆是由它限定边界定义的,因此无法保证它以(0,0)为中心。

让我们调用中心(cx,cy),然后椭圆的等式变为

(x-cx)^2/a^2 + (y-cy)^2/b^2 = 1

而不是原来的

x^2/a^2 + y^2/b^2 = 1

我认为,简单修复是将行转换为(cx,cy)并将结果翻译回来,如下所示:

...
double m = (in_y2-cy) - k*(in_x2-cx);
...
double ex1 = (-B1 + D/(2*A1)) + cx;
double ey1 = k*(ex1-cx) + m + cy;
double ex2 = (-B1 - D/(2*A1)) + cx;
double ey2 = k*(ex2-cx) + m + cy;

更优雅的修复是为了解决椭圆的正确方程,但这会导致B1C1更难以理解的公式:

double B1 = (2*k*(m-cy))/(b*b) - (2*cx)/(a*a);
double C1 = (m-cy)*(m-cy)/(b*b) - 1 + (cx*cx)/(a*a);

作为最后一点,请注意这会导致垂直线分解,因为r2 = 0因此k未定义。

答案 2 :(得分:1)

你可以把你的代码放进去,以便我们看看它是否正确吗?

无论如何,这是一个算法: http://mathworld.wolfram.com/Ellipse-LineIntersection.html

请注意,由于它有一个平方根,因此您可能会得到一个不准确的解决方案。

答案 3 :(得分:0)

Line2D.Double line = new Line2D.Double(x1,y1,x2,y2);

Ellipse2D.Double ellipse = new Ellipse2D.Double(x,y,width,height);

int resolution = 1000;
int x_distance = ellipse.getWidth()/2;
int y_distance = ellipse.getHeight()/2;

double angle = 360.0/(double)resolution;

Point center = new Point(width/2,height/2);
Point point = new Point();

for (int index = 0; index < resolution; index++)
{
    int x = (center.x+x_distance)*Math.sin(Math.toRadians(angle*index)));
    int y = (center.y+y_distance)*Math.cos(Math.toRadians(angle*index)));

    Ellipse2D.Double dot = new Ellipse2D.Double(x,y,1,1);

    if (line.intersects(dot.getBounds()))
    {
       point.setLocation(x,y);
       index = resolution;
    }
}