processingで再帰について学んでいたのですがこの曲線の描き方だけがどうもうまく再帰プログラムを組むことができません。
どのように書けばうまくこのように描けるのでしょうか。ちなみに再帰ではなく分割統治法なら4つのパターンに分けて処理すればなんとかなりそうだと分かるのですが...。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
再帰も一種の分割統治法ですのでヒルベルト曲線の描画ルールについて検討する際の方針は概ね同じと言えると思います。
ヒルベルト曲線はタートルグラフィックの例題としてよく登場すると思います。タートルグラフィックというのは「今ペンがある地点」から「どの方向へ」「どのような線を描くか」で線画を描いていく手法です。
大雑把な方針はある方向へペンを移動する際に3つの線分(レベル1での3辺)を描きながら、各々の線分の間に一つ下のレベルのヒルベルト曲線を(方向に注意しながら)描画するというものです。
すみませんが、詳細な説明を言葉でするよりコードを提示した方が(回答する側にとって)楽なので詳しくはコード例を参考にしてみてください。
本質はhilbert関数です。殆ど答えみたいなものですが、完全なコードを書いてしまうと無粋なので若干部分だけ書かずに残してあります。(A)~(C)に何を埋めればうまく描画できるか考えてみてください。
Java
1static final int[][] dirs = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 }}; 2 3int level; 4float px, py, dist; 5 6// 指定方向へ単位直線を描画する 7 8void turtle(int dir) { 9 dir = dir & 3; 10 float nx = px + dirs[dir][0] * dist; 11 float ny = py + dirs[dir][1] * dist; 12 line(px, py, nx, ny); 13 px = nx; 14 py = ny; 15} 16 17// 指定レベルのヒルベルト曲線を描く 18// dirはペンの(このレベルでの)最終的な移動方向。 19// spinは右回りか左回りかを示す。 20 21void hilbert(int level, int dir, int spin) { 22 if (level == 0) return; 23 24 hilbert(level - 1, dir + spin, -spin); 25 turtle(dir + spin); 26 hilbert(level - 1, ...); // (A) 27 turtle(dir); 28 hilbert(level - 1, ...); // (B) 29 turtle(dir - spin); 30 hilbert(level - 1, ...); // (C) 31} 32 33// level 1~7を繰り返し描画 34 35void setup() { 36 size(256, 256); 37 level = 1; 38 frameRate(1); 39} 40 41void draw() { 42 fill(255); 43 noStroke(); 44 rect(0, 0, width, height); 45 46 stroke(0); 47 int div = 1 << level; 48 dist = width / (float)div; 49 println(level + ":" + dist); 50 px = py = dist / 2; 51 52 hilbert(level, 3, 1); 53 54 level = level % 7 + 1; 55}
投稿2018/06/07 08:20
総合スコア18402
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/07 11:25