1

(別のクラスの)lineListという配列からLine2D値を読み取り、それらをlistという新しい配列に格納する小さなコードブロックがあります。ここから、すべてのライン値をポリゴンポイント(ラインエンドの各x、y座標のポイント)に変換しようとしています。

これまでのところ、私はそれを機能させていますが、追加された配列の最初の行の最初のポイント(それは私が思うものです)では機能せず、これを含めようとしたので、これに対する解決策を見つけるのに苦労しています最初のifステートメント。

私はこれに関して誰もが私に提供することができるどんな助けにも大いに感謝します。

以下は、Line2D値からポイントを追加するために使用しているコードです。

Polygon p = new Polygon();
    ArrayList<Line2D> list = new ArrayList<Line2D>();
    Color pixel;
    boolean firstTime = true;

    list = segmentation.getLineList();

    //loop through lineList and add all x and y coordinates to relative x and y arrays
    for(int i = 0; i < list.size(); i++) {
        if(firstTime == true){
            Line2D line = list.get(i);
            Point2D startPoint = line.getP1();
            Point2D endPoint = line.getP2();
            int startX = (int) startPoint.getX();
            int startY = (int) startPoint.getY();
            int endX = (int) endPoint.getX();
            int endY = (int) endPoint.getY();
            p.addPoint(p.xpoints[i] = startX, p.ypoints[i] = startY);
            p.addPoint(p.xpoints[i] = endX, p.ypoints[i] = endY);
            startPoint = null;
            endPoint = null;
            line = null;
            firstTime = false;
        }
        else {
            Line2D line = list.get(i);
            Point2D endPoint = line.getP2();
            int endX = (int) endPoint.getX();
            int endY = (int) endPoint.getY();
            p.addPoint(p.xpoints[i] =  endX, p.ypoints[i] = endY);
            endPoint = null;
            line = null;    
        }
    }

以下は、ポリゴンポイントに含まれていない最初のポイント(最下部のポイント)の例です。 ここに画像の説明を入力してください

4

1 に答える 1

4

私には重複したコードがたくさんあるようです。デバッグを試す前に、コードをリファクタリングして、理解とデバッグを簡単にしましょう。

リファクタリング

引き出すことができるコードの最初のビットは、ポリゴンにポイントを追加するコードです。これが新しい方法です。

protected void addPoint(Polygon p, Point2D point) {
    int x = (int) point.getX();
    int y = (int) point.getY();
    p.addPoint(x, y);
}

さて、私は1回のリファクタリングでこれに到達しませんでした。エンドポイントコードは同じだったので、最初に引き出しました。コードをもう少し考えた後、それを一般化して、開始点コードに使用できるようにしました。

このコード行を最初に見たとき

 p.addPoint(p.xpoints[i] = startX, p.ypoints[i] = startY);

私は思った、WTF?メソッド呼び出しで値を設定する人を見たことがありません。where句では、確かに。

約5分間考えた後、addPointメソッドの実行後にPolygonクラスの内部値が設定されていることに気付きました。これは他のメソッド呼び出しで役立つ場合がありますが、ここでは必要ありません。メソッド呼び出しは次のように簡略化できます

p.addPoint(x, y);

Java開発者は、クラス変数を非公開にするさらに別の理由が必要な場合、これは本当に良い理由です。setterメソッドでクラス変数を設定した後、他のユーザーがクラス変数を設定できないようにします。

プライミングリード

プライミング読み取りと呼ばれるあまり知られていないアルゴリズムを使用すると、初回の切り替えと多くのコードを取り除くことができます。

ほとんどのforループには、ループの最初のステートメントとしてinputステートメントがあります。ループのfor (String s : stringList)構築により、入力ステートメントがループの最初のステートメントであるという事実が隠されます。

ただし、プライミング読み取りが必要なメソッドがある場合もあります。この方法はその1つです。

擬似コードでは、プライミング読み取りは次のように機能します。

Read input
for loop
    process input
    read input
end loop
process last input

プライミング読み取りを使用することで、createPolygonメソッドを大幅に簡素化することができました。

この考えを読んでいるCobolプログラマーは誰でも、「うん、プライミングを読んだ」。

Javaプログラマーは、このプライミング読み取りのアイデアを念頭に置いてください。それほど頻繁には使用しませんが、ご覧のとおり、場合によっては必要なコードの量が大幅に削減されます。

リファクタリングされたコード

public Polygon createPolygon(Segmentation segmentation) {
    Polygon p = new Polygon();
    List<Line2D> list = segmentation.getLineList();
    if (list.size() < 2) return p;

    Line2D line = list.get(0);
    addPoint(p, line.getP1());

    // loop through lineList and add all x and y coordinates to relative x
    // and y arrays
    for (int i = 1; i < list.size(); i++) {
        addPoint(p, line.getP2());
        line = list.get(i);
    }

    addPoint(p, line.getP2());
    return p;
}

protected void addPoint(Polygon p, Point2D point) {
    int x = (int) point.getX();
    int y = (int) point.getY();
    p.addPoint(x, y);
}

コードにさらに2つのことを行いました。

  1. 2行未満のテストを追加しました。基本的に、三角形(ポリゴン)を作成するには、少なくとも2本の線が必要です。1行または0行のメソッドを実行する意味はありませんでした。

  2. ArrayList参照をListに変更しました。Javaでは、具象クラスよりもインターフェースを使用することをお勧めします。コードで使用しているListメソッドはgetメソッドだけなので、インターフェイスを使用できます。インターフェイスを使用する利点は、createPolygonメソッドが、getLineListメソッドがArrayList、LinkedList、またはListを実装するカスタムクラスを返すかどうかを気にしないことです。これにより、将来の変更が容易になります。

于 2013-02-20T19:12:07.860 に答える