我完全卡住了。 我有一个椭圆和一条线。线由两个点设置,椭圆 - 左下角和右上角。我必须使用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;
答案 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;
更优雅的修复是为了解决椭圆的正确方程,但这会导致B1
和C1
更难以理解的公式:
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;
}
}