2014-02-23 5 views
1

PathIterator를 사용하여 곡선 경로를 계산할 수 있도록 Shape 객체의 중심을 계산하려고하지만 표준 1x1 사각형의 중심을 찾을 때 내 getCenter() 메서드는 점을 반환합니다.Java PathIterator - 도형의 중심을 정확하게 계산하려면 어떻게해야합니까?

Point2D.Double[0.3333333333333333, 0.3333333333333333] 

내 getCenter() 메소드 :

shape = new Rectangle2D.Double(0, 0, 1, 1); 


public Point2D.Double getCenter() 
     { 
      ArrayList<Point2D.Double> points = new ArrayList<Point2D.Double>(); 
      double[] arr = new double[6]; 
      for(PathIterator pi = shape.getPathIterator(null); !pi.isDone(); pi.next()) 
      { 
       pi.currentSegment(arr); 
       points.add(new Point2D.Double(arr[0], arr[1])); 
      } 

      double cX = 0; 
      double cY = 0; 
      for(Point2D.Double p : points) 
      { 
       cX += p.x; 
       cY += p.y; 
      } 
        System.out.println(points.toString()); 
      return new Point2D.Double(cX/points.size(), cY/points.size()); 
     } 

내가 points.toString()을 인쇄에 있음을 발견했다, 나는 콘솔이 얻을 :

[Point2D.Double[0.0, 0.0], Point2D.Double[1.0, 0.0], Point2D.Double[1.0, 1.0], Point2D.Double[0.0, 1.0], Point2D.Double[0.0, 0.0], Point2D.Double[0.0, 0.0]] 

입력 Shape 객체가 Rectangle2D.Double (0, 0, 1, 1)이라는 점을 감안할 때, 예상했던 네 개가 아니라, 점 배열에 여섯 개의 항목이 있음을 발견했습니다. 분명히 그것은 내가 원하는 것보다 두 번 더 (0, 0) 점에 대한 것이고, 왜 그런지 혼란 스럽습니다. PathIterator.isDone() 메서드의 결과입니까? 내가 잘못 사용하고 있습니까? PathIterator가 내 문제를 해결할 수 없다면 어떻게 될까요?

답변

0

이미 지적했듯이 PathIterator는 다른 유형의 세그먼트를 반환합니다. SEG_LINETO에 포함 된 점만 고려할 때 이미 만족스러운 결과를 얻어야합니다. 그러나 다른 모양에도 SEG_QUADTO 및 SEG_CUBICTO가있을 수 있습니다. 당신이 적절한 평탄

PathIterator pi = shape.getPathIterator(null, flatness); 

과 함께 사용하는 PathIterator를 만들 때, 그것은 단지 직선 세그먼트가 포함됩니다 :이 쉽게 병합 사용하는 PathIterator를 사용하여 방지 할 수 있습니다.

import java.awt.Shape; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.PathIterator; 
import java.awt.geom.Point2D; 
import java.awt.geom.Rectangle2D; 

public class ShapeCenter 
{ 
    public static void main(String[] args) 
    { 
     System.out.println(computeCenter(new Ellipse2D.Double(-10,-10,20,20))); 
     System.out.println(computeCenter(new Rectangle2D.Double(0,0,1,1))); 
    } 

    public static Point2D computeCenter(Shape shape) 
    { 
     final double flatness = 0.1; 
     PathIterator pi = shape.getPathIterator(null, flatness); 
     double coords[] = new double[6]; 
     double sumX = 0; 
     double sumY = 0; 
     int numPoints = 0; 
     while (!pi.isDone()) 
     { 
      int s = pi.currentSegment(coords); 
      switch (s) 
      { 
       case PathIterator.SEG_MOVETO: 
        // Ignore 
        break; 

       case PathIterator.SEG_LINETO: 
        sumX += coords[0]; 
        sumY += coords[1]; 
        numPoints++; 
        break; 

       case PathIterator.SEG_CLOSE: 
        // Ignore 
        break; 

       case PathIterator.SEG_QUADTO: 
        throw new AssertionError(
         "SEG_QUADTO in flattening path iterator"); 
       case PathIterator.SEG_CUBICTO: 
        throw new AssertionError(
         "SEG_CUBICTO in flattening path iterator"); 
      } 
      pi.next(); 
     } 
     double x = sumX/numPoints; 
     double y = sumY/numPoints; 
     return new Point2D.Double(x,y); 
    } 

} 
0

PathIterator은 다른 유형의 세그먼트를 정의하므로이 사실에 유의해야합니다. 하위 경로의 시작을 정의하는 SEG_MOVETO 세그먼트와 하위 경로의 끝에 SEG_CLOSE를 추가로 반환하므로 예제에서 6 개의 세그먼트가 생성됩니다. 당신이 당신의 형상의 라인의 끝점을 얻고 싶은 경우에, 당신은 다음과 같이 코드를 변경해야합니다

for(PathIterator pi = shape.getPathIterator(null); !pi.isDone(); pi.next()) 
    { 
     if(pi.currentSegment(arr) == PathIterator.SEG_LINETO) { 
      points.add(new Point2D.Double(arr[0], arr[1])); 
     } 
    } 
0

을 당신이 그것을 잘못사용하고 있는지 모르지만, 당신이 차지하지 않습니다 측면은 PathIterator입니다. PathIterator는 기하학적 도형을 그리 많이 나타내는 것이 아니라 그리는 동안 가져와야 할 경로입니다. 그래서 그 점은 '펜'이 취해야 할 경로의 유형을 나타냅니다.

  1. SEG_MOVETO
  2. SEG_LINETO
  3. SEG_LINETO
  4. SEG_LINETO
  5. SEG_LINETO
  6. SEG_CLOSE

예를 들어, 구형 경로는 다음 세그먼트를 만들어 명백히 경로는 다음과 같아야합니다.

  • 펜이 있던 곳 어디에서나 이동하고 그리지 마십시오.
  • 펜이 다음에 그려지는 위치에서이 경로를 닫습니다.

세그먼트 형식은 currentSegment의 반환 값입니다. 당신은 단지 당신이 세그먼트 '에 선'을 확인할 수 있습니다 다각형에있는 점을 캡처하려면 다음 사각형 같은 단순한 다각형을 위해 작동 할

if(pi.currentSegment(arr) == PathIterator.SEG_LINETO) { 
    points.add(new Point2D.Double(arr[0], arr[1])); 
} 

. 주어진 Rectangle의 경우 [0.5, 0.5]가 반환됩니다. 관심있는 결과를 가정합니다.

반면에 폴리곤이 아닌 도형이 있으므로이 접근법에주의해야합니다. .