1

PathIterator を使用して任意の Shape オブジェクトの中心を計算し、曲線のパスを考慮できるようにしようとしていますが、標準の 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.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) であることを考えると、points 配列には 4 つではなく、6 つのエントリがあることに気付きました。明らかに、それはポイント (0, 0) を私が望むよりも 2 回多く説明していて、それがなぜなのか混乱しています。PathIterator.isDone() メソッドの結果ですか? 私はそれを間違って使用していますか?PathIterator ができない場合、どうすれば問題を解決できますか?

4

3 に答える 3

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]));
        }
    }
于 2014-02-23T21:17:08.677 に答える
0

間違って使用しているかどうかはわかりませんが、 PathIteratorの側面を考慮していません。PathIterator は、幾何学的形状を表すのではなく、描画中にたどる必要があるパスを表します。したがって、そのポイントは、「ペン」がたどるべきパスのタイプも表します。たとえば、Rectangle の場合、パスは次のセグメントを作成します。

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

明らかにパスは次のようにする必要があるためです。

  • ペンがあった場所から、描画するのではなく、移動します。
  • ペンが次に描画するものから、このパスを閉じます。

セグメントのタイプは の戻り値ですcurrentSegment。ポリゴン上にあるポイントのみをキャプチャしたい場合は、'line to' セグメントを確認できます。

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

これは、Rectangle のような単純なポリゴンで機能します。指定された Rectangle に対して、 [0.5, 0.5] が返されます。これは、あなたが興味を持っている結果であると想定しています。

一方、ポリゴンではない形状もあるので、このアプローチには注意が必要です。

于 2014-02-23T21:17:24.680 に答える