我有一个椭圆,中点'mid',水平半径'h'和垂直半径'v'和Line2D。椭圆和线交点JAVA
现在我需要一些代码来计算两个交点。 我已经尝试了一些代码,并尝试在我自己的,但总是有一个错误。
有人有一些工作代码吗?
我有一个椭圆,中点'mid',水平半径'h'和垂直半径'v'和Line2D。椭圆和线交点JAVA
现在我需要一些代码来计算两个交点。 我已经尝试了一些代码,并尝试在我自己的,但总是有一个错误。
有人有一些工作代码吗?
我会使用内置的椭圆和线/多边形类有他们都有方法来确定碰撞和交汇
您将需要使用代数来解决这两个方程,它会得到一个有点乱。首先,你必须让椭圆的原点为中心在你的坐标轴写出来的椭圆
(1) (x/h)^2 + (y/v)^2 = 1
和行格式
(2) y = ax + b
首先,移位。你可以通过从线上减去中间值来实现。一旦你计算出相交点,通过增加中点将它们移回去。
您可以从线的起点和终点计算delta-y/delta-x的线性斜率。你将不得不检查斜坡是否垂直。如果斜率是垂直的,则只需检查线点的x值是否落在椭圆的位置,然后轻松计算这些值。在纸上画出来,看看如何计算它。
现在假设斜坡不是垂直的。既然你从行中知道y,就可以代入(1)。简化给出了二次方程。
(3) ((ah)^2+v^2)x^2 + (2abh^2)x + ((hb)^2-(hv)^2) = 0
使用二次公式给出交点x坐标的两个值。如果x有两个实数值,则有两个交点。如果x只有一个实数解,则有一个交点。如果x没有真正的解决方案,则不存在交集。
鉴于斧^ 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是最小的,x2是线的最大x端点,y1是最小的,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);
}
随意检查我的代数和我的代码,但你应该通过每个代数一步仔细去解决这个问题。
当该线由两个点P0
和P1
给出时,该线上的任何点是(X, Y) = (X0, Y0) + t (X1 - X0, Y1 - Y0) = (X0, Y0) + t (DX, DY)
。
椭圆是(X - Xm)²/h² + (Y - Ym)²/v² = 1
。
我们将使用一个技巧来简化计算:采取一切X
,减去由h
Xm
和鸿沟,让x
;取全部Y
,减去Ym
并除以h
,给出y
。这将把椭圆变成一个以原点为中心的圆。 (如果您愿意,可以在不减少坐标的情况下进行所有计算。)
现在,(x, y) = (x0, y0) + t (dx, dy)
和x² + y² = 1
。
或(t dx + x0)² + (t dy + y0)² = 1
。
或(dx² + dy²) t² + 2 (dx x0 + dy y0) t + (x0² + y0² - 1) = 0
。
解决t
的二次方程式。如果有真正的根源,则可以通过条件0 <= t <= 1
检查它们是否属于线段。交叉点本身由第一个等式给出。
我找不到给我这个信息的方法。最好的方法是正确的? – user3658206
http://docs.oracle.com/javase/7/docs/api/java/awt/geom/Ellipse2D.html – user3730340
和什么方法? – user3658206