Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PathIterator-如何准确计算形状对象的中心?_Java_Shapes_Centroid_Path Iterator - Fatal编程技术网

Java PathIterator-如何准确计算形状对象的中心?

Java PathIterator-如何准确计算形状对象的中心?,java,shapes,centroid,path-iterator,Java,Shapes,Centroid,Path Iterator,我尝试使用PathIterator计算任何形状对象的中心,以便可以计算弯曲路径,但在找到标准1x1矩形的中心后,我的getCenter方法返回点: Point2D.Double[0.3333333333333333, 0.3333333333333333] 我的getCenter方法: shape = new Rectangle2D.Double(0, 0, 1, 1); public Point2D.Double getCenter() { Arr

我尝试使用PathIterator计算任何形状对象的中心,以便可以计算弯曲路径,但在找到标准1x1矩形的中心后,我的getCenter方法返回点:

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数组中有六个条目,而不是我预期的四个条目,因为输入图形对象是矩形2D.Double0,0,1,1。很明显,它比我想要的多解释了两次0点,我不明白为什么会这样。这是PathIterator.isDone方法的结果吗?我用错了吗?如果PathIterator不能解决我的问题,该怎么办?

定义了不同类型的段,您应该注意这个事实。在您的示例中有6个段,因为它还额外返回SEG_MOVETO段(定义子路径的开始)和SEG_CLOSE(子路径的结束)。如果只想获取形状线条的端点,则应按如下方式更改代码:

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

我不确定你是否用错了,但你没有说明问题的一个方面。PathIterator与其说代表一个几何图形,不如说代表一个在绘制时应该采用的路径。因此,它的点也代表了“笔”应该走的路径类型。例如,对于矩形,路径将生成以下线段:

SEG_MOVETO 塞古·莱内托 塞古·莱内托 塞古·莱内托 塞古·莱内托 SEG_CLOSE 因为路径显然应该:

无论笔在哪里,都要移动,而不是画画。 将此路径与笔下一步绘制的内容隔开。 段的类型是currentSegment的返回值。如果只想捕获多边形上的点,可以检查“直线到”线段:

if(pi.currentSegment(arr) == PathIterator.SEG_LINETO) {
    points.add(new Point2D.Double(arr[0], arr[1]));
}
这将适用于矩形等简单多边形。对于给定的矩形,它将返回[0.5,0.5],这是我假设您感兴趣的结果


另一方面,有些形状不是多边形,因此我会小心使用这种方法。

正如前面所指出的,PathIterator返回不同类型的段。仅考虑SEG_LINETO中涉及的点时,应已获得令人满意的结果。然而,考虑到也可能有其他形状的SexGuthto和SeCube CuButo。使用展平PathIterator可以很容易地避免这些问题:使用

PathIterator pi = shape.getPathIterator(null, flatness);
如果具有适当的平面度,则它将仅包含直线段

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

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

}