我有一個橢圓,中點'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