2014-06-11 2 views
1

중간 반경이 '중'이고 반경이 'h'이고 수직 반경이 'v'인 타원과 Line2D가 있습니다.타원 및 선분 교차 JAVA

이제 두 코드의 두 교차점을 계산하는 코드가 필요합니다. 나는 이미 몇 가지 코드를 시도하고 혼자 시도했지만 실수는 항상있다.

누군가 작업 코드가 있습니까?

답변

1

나는이 둘은 충돌과 교차를 결정하는 방법이 타원 라인/다각형 클래스에 내장 된 사용합니다

+0

이 정보를 제공하는 방법을 찾을 수 없습니다. 방법은 올바른 방법인가요? – user3658206

+0

http://docs.oracle.com/javase/7/docs/api/java/awt/geom/Ellipse2D.html – user3730340

+0

과 같은 방법? – user3658206

2

당신은 두 개의 방정식을 해결하기 위해 대수를 사용해야합니다, 그것은 조금 지저분한 얻을 것이다 . 먼저 타원이 원점을 중심으로 귀하의 좌표축을 통해 형식

(2) y = ax + b 

첫째, 변화에 타원

(1) (x/h)^2 + (y/v)^2 = 1 

와 라인을 작성해야합니다. 라인에서 mid를 빼서 그렇게 할 수 있습니다. 교차점을 계산했으면 mid를 추가하여 교점을 이동하십시오.

선의 시작점과 끝점에서 delta-y/delta-x의 선형 기울기를 계산할 수 있습니다. 경사면이 수직인지 확인해야합니다. 기울기가 수직 인 경우 선의 x 값이 타원의 위치에 속하는지 여부를 확인한 다음 값을 쉽게 계산하면됩니다. 종이에 그려 그것을 계산하는 방법을 참조하십시오.

기울기가 수직이 아니기 때문에 이제 가정하십시오. 선에서 x의 관점에서 y를 알기 때문에 (1)을 대입하여 대입하십시오. 단순화하면 2 차 방정식이됩니다.

(3) ((ah)^2+v^2)x^2 + (2abh^2)x + ((hb)^2-(hv)^2) = 0 

두 번째 수식을 사용하면 교차점의 x 좌표에 대한 두 값이 제공됩니다. x에 대해 두 개의 실제 값이있는 경우 두 개의 교차점이 있습니다. x에 대해 하나의 실제 솔루션 만 있다면, 하나의 교차점이 있습니다. x에 대한 실제 해결책이 없다면 교차가 없다.

주어 AX^2 + BX + C = O, X는

x = (1/2a)(-b +- Sqrt(b^2 - 4ac)) 

하자 D 주어진다 = B^2 - 4ac

D <이 0이면 존재없이 교차

는 D> 0 개의 교차점이 존재하면 D = 0 번 교차

있으면

012,351

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); 
} 

내 대수 내 코드를 확인 자유롭게 만든 예제 방법입니다,하지만 당신은 신중하게 각 대수 단계를 이동하여이 문제를 해결해야한다.

0

두 줄이 P0P1 인 경우 줄을 따라 모든 점은 (X, Y) = (X0, Y0) + t (X1 - X0, Y1 - Y0) = (X0, Y0) + t (DX, DY)입니다.

타원은 (X - Xm)²/h² + (Y - Ym)²/v² = 1입니다.

우리는 계산을 단순화하기 위해 트릭을 사용합니다

는 : x을 제공, 모든 X 걸릴 h에 의해 Xm과 분열을 빼기; 모두 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에 대한이 2 차 방정식을 풀어 라. 실제 루트가있는 경우 해당 라인 세그먼트에 속하는지 0 <= t <= 1으로 확인할 수 있습니다. 교차점 자체는 첫 번째 방정식에 의해 주어집니다.