9

だから私は、OpenGL を使用して Koch の雪片を描画することになっている再帰的なプログラムをプログラミングしています。1 つの小さな問題を除いて、プログラムは基本的に機能しています。再帰が深くなるほど、特定の 2 つの頂点が得られなくなります。下の写真。

編集: OpenGL の側面はあまり気にしません。その部分は省略しました。OpenGL を知らない場合、glVertex が行うことは、2 つのメソッド呼び出しで指定された 2 つの頂点間に線を引くことだけです。その drawLine(v1,v2) のふりをします。同じ違い。

ポイントを見つけるための私の方法が原因であると思われますが、間違っているように見えるものは何も見つかりません。

私は基本的に標準的な描画方法に従っています。関連するコードスニップは次のとおりです

(V は頂点 V1 は左下隅、v2 は右下隅、v3 は上部隅):

        double dir = Math.PI;
        recurse(V2,V1,n);

        dir=Math.PI/3;
        recurse(V1,V3,n);

        dir= (5./3.)* Math.PI ;
        recurse(V3,V2,n);

再帰的な方法:

public void recurse(Point2D v1, Point2D v2, int n){
    double newLength = v1.distance(v2)/3.;
    if(n == 0){
        gl.glVertex2d(v1.getX(),v1.getY());
        gl.glVertex2d(v2.getX(),v2.getY());

    }else{

        Point2D p1 = getPointViaRotation(v1, dir, newLength);
        recurse(v1,p1,n-1);
        dir+=(Math.PI/3.);

        Point2D p2 = getPointViaRotation(p1,dir,newLength);
        recurse(p1,p2,n-1);
        dir-=(Math.PI*(2./3.));

        Point2D p3 = getPointViaRotation(p2, dir, newLength);
        recurse(p2,p3,n-1);
        dir+=(Math.PI/3.);

        recurse(p3,v2,n-1);
    }

}

私の数学が問題だと本当に思っていますが、これは私には正しいようです:

public static Point2D getPointViaRotation(Point2D p1, double rotation, double length){
    double xLength = length * Math.cos(rotation);
    double yLength = length * Math.sin(rotation);
    return new Point2D.Double(xLength + p1.getX(), yLength + p1.getY());
}

N = 0 (万事順調):

ここに画像の説明を入力

N = 1 (たぶん、少し曲がっているかもしれません)

ここに画像の説明を入力

N = 5 (ワット)

ここに画像の説明を入力

4

3 に答える 3

4

コードに関して明らかな問題は見当たりません。しかし、私は何が起こるかについて理論を持っています。

グラフ内のすべてのポイントは、その前のポイントの位置に基づいているようです。そのため、このプロセス中に発生する丸め誤差は最終的に蓄積し始め、最終的には混乱して途方に暮れます。

手始めに、内部呼び出しの丸め誤差の影響を制限するために、再帰する前に各セグメントの開始点と終了点を計算します。

于 2013-10-02T07:28:38.417 に答える
2

Koch のスノーフレークについての 1 つのことは、アルゴリズムが丸めの問題を 1 回引き起こすことです (これは再帰的であり、すべての丸め誤差が加算されます)。コツは、できるだけ長く続けることです。できることは次の 3 つです。

  • もっと詳しく知りたければ、 の可能性を広げるしかありませんDouble。独自の範囲の座標を使用して、実際に画面にペイントするたびにそれらを画面座標に変換する必要があります。独自の座標はズームして、最後の再帰ステップ (最後の三角形) を、たとえば 100x100 の座標系で表示する必要があります。その上に新しい三角形を 3 つ計算し、画面座標に変換してペイントします。
  • 線分dir=Math.PI/3;は ではなく 3 で割り(double) 3ます。.の後にを追加3
  • 必ずPoint2D.Doubleどこでも使用してください。あなたのコードはそうすべきですが、どこにでも明示的に書きます。

あなたはまだ素敵な雪片を持っていますが、 Stackoverflowを取得すると、ゲームに勝ちました。

于 2013-10-02T07:43:11.717 に答える