あれから10年。プロデルでシダを描画するプログラムを作ってみました。
元ネタはこちらです。
窓としてウィンドウを作る
その内容は「バーンズリーのシダ」
その大きさは{700,700}
その設計スケール比率は{144,144}
窓を表示する
かめさんというカメを作る
かめさんの場所は、窓
かめさんの太さは1
かめさんの色は、緑
かめさんを表示する
浮動小数座標({0,0})を作って初期点とする
20だけ初期点にシダを描く
かめさんの位置は{0,0}
待機する
【点:浮動小数座標】を、第一横変換する手順 //W1x
0.836 * 点の横 + 0.044 * 点の縦を返す
終わり
【点:浮動小数座標】を、第一縦変換する手順 //W1y
-0.044 * 点の横 + 0.836 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第二横変換する手順 //W2x
-0.141 * 点の横 + 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第二縦変換する手順 //W2y
0.302 * 点の横 + 0.141 * 点の縦 + 0.127を返す
終わり
【点:浮動小数座標】を、第三横変換する手順 //W3x
0.141 * 点の横 - 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第三縦変換する手順 //W3y
0.302 * 点の横 + 0.141 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第四横変換する手順 //W4x
0を返す
終わり
【点:浮動小数座標】を、第四縦変換する手順 //W4y
0.175337 * 点の縦を返す
終わり
【回数】だけ【点:浮動小数座標】に、シダを描く手順
浮動小数座標({0,0})を作って次点とする
回数が0より大きければ
点を第一横変換して次点の横とする
点を第一縦変換して次点の縦とする
回数-1だけ次点にシダを描く
1から10までの乱数が4より小さければ
点を第二横変換して次点の横とする
点を第二縦変換して次点の縦とする
回数-1だけ次点にシダを描く
そして
1から10までの乱数が4より小さければ
点を第三横変換して次点の横とする
点を第三縦変換して次点の縦とする
回数-1だけ次点にシダを描く
そして
1から10までの乱数が4より小さければ
点を第四横変換して次点の横とする
点を第四縦変換して次点の縦とする
回数-1だけ次点にシダを描く
そして
でなければ
かめさんの位置は{点の横*500+200,500-点の縦*500}
かめさんが点を打つ
そして
終わり
できるだけ英字を使わずにプログラミング
日本語プログラミング言語ということで、英字をできるだけ使わずにプログラムを書いてみました。
ここでは座標であるx, yをそれぞれ別の変数とはせずに「浮動小数座標」種類に入れて、縦・横で書くことにしました。このように書いたのは、手順では引数に助詞を指定する必要であるため、できるだけ引数を少なくしたかったという理由もあります。もちろん義務教育で、数式には触れていますので、無理日本語を使わずにx,yといった記号をそのままでよいと思います。
実行結果
実行して、数十分しばらく待っていると、徐々にシダのような模様が浮かび上がってきます。
まとめ
プロデルは、日本語でプログラムを書く点だけが違うだけで、他の多くのプログラミング言語と同じ機能を持っています。プロデルで日本語でプログラミングを学んでも、アルゴリズムや設計技法は変わらないので、のちに別のプログラミング言語を使うことになっても、すぐに慣れることでしょう。
いつもお世話になっております。アークです。
最近、精力的に記事を書かれていて何れも興味深いのですが、
理解が追い付かないのでじっくりと読み返しさせていただきます。
また、最新の「バーンズリーのシダ」は息抜きに良いと思ったのですが、
アルゴリズムそのものは難解というか見えて来ません。
私は「バーンズリーのシダ」そのものを知らなかったのですが、
プログラミングの世界では結構有名で色々な言語で取り上げられていました。
分野的に想像がつくProcessingを始めBASICでも紹介記事が有りました。
面白そうなので早速動かしてみました。
10年以上も前の私のマシンでは7分40秒掛かってカメさんが動きを止めました。
本領を発揮しそうなProcessingでも試してみたら何と4秒でした。
同じくBASICでも4秒でした。
この差がどこから来るのかを考えた時、
亀とは思えぬ速さで動くカメさんが原因ではないかと思い、
下記のようにコードを修正してみました。
窓としてウィンドウを作る
その内容は「バーンズリーのシダ」
その大きさは{650,850}
その設計スケール比率は{144,144}
窓を表示する
図形描画の太さを1に変える
図形描画の色を緑に変える
浮動小数座標({00,0})を作って初期点とする
20だけ初期点にシダを描く
待機する
【点:浮動小数座標】を、第一横変換する手順 //W1x
0.836 * 点の横 + 0.044 * 点の縦を返す
終わり
【点:浮動小数座標】を、第一縦変換する手順 //W1y
-0.044 * 点の横 + 0.836 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第二横変換する手順 //W2x
-0.141 * 点の横 + 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第二縦変換する手順 //W2y
0.302 * 点の横 + 0.141 * 点の縦 + 0.127を返す
終わり
【点:浮動小数座標】を、第三横変換する手順 //W3x
0.141 * 点の横 – 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第三縦変換する手順 //W3y
0.302 * 点の横 + 0.141 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第四横変換する手順 //W4x
0を返す
終わり
【点:浮動小数座標】を、第四縦変換する手順 //W4y
0.175337 * 点の縦を返す
終わり
【回数】だけ【点:浮動小数座標】に、シダを描く手順
浮動小数座標({0,0})を作って次点とする
もし回数が0より大きければ
点を第一横変換して次点の横とする
点を第一縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし1から10までの乱数が4より小さければ
点を第二横変換して次点の横とする
点を第二縦変換して次点の縦とする
回数-1だけ次点にシダを描く
点を第三横変換して次点の横とする
点を第三縦変換して次点の縦とする
回数-1だけ次点にシダを描く
点を第四横変換して次点の横とする
点を第四縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし終わり
そうでなければ
図形描画によって、窓の{点の横*500+200,500-点の縦*500}へ点を描く
もし終わり
終わり
結果は予想に反して30分14秒でした。
どうやら見当違いだったようです。
スレッドが使えたなら改善しそうですが、
再帰処理が行われているので使えません。
やはりこういうプログラムを目の当たりにすると、
プラグラムはアルゴリズムと繰返しが大事なのだと思い知らされます。
また、何か方法を思いついたら再挑戦んしてみたいと思います。
コメントありがとうございます。
巷のプログラムをプロデルに移植するだけでも、勉強になることは多いかと思います。
実行スピードについては、プロデルそのものの原因もありそうなので、追及して徐々に改善したいと思います。
こんにちは。アークです。
フラクタルも再帰処理も得意では無いので難しいのですが、
朧気ながら少し分かった事が有ります。
これは幾何学の相似形を四段階実行しているようですね。
再帰処理を非再帰処理に書換えられたら改善できそうです。
処理を開始して数秒間は目に見えて描画が進んでいますが、
その後は目立った動きが無いので無駄な処理が有るような気がします。
再帰処理のプログラムを追うのは難しいです。
またまたアークです。
当初は7分40秒掛かっていましたが、
その後、工夫をして大幅に短縮する事に成功しました。
現在はデザイナ上で実行して18秒程です。
コンパイルもしてみましたが17秒と誤差の範囲でした。
数秒にまで縮まるかと期待したのですが残念な結果となりました。
◆動作環境情報◆
プロデル 2.0.1278
Windows 10 Pro 64ビット
メモリ:7.87 GB
下記が修正後のソースです。
【C:色情報】は{0,128,0}
写真という画像(400,530)を作る
開始時刻は、今の時刻
メイン画面を表示する
浮動小数座標({0,0})を作って初期点とする
20だけ初期点にシダを描く
情報音を鳴らす
メイン画面のピクチャー1の画像は、写真
終了時刻は、今の時刻
エンドという日時期間形式(「[終了時刻]」)を作る
スタートという日時期間形式(「[開始時刻]」)を作る
経過時間は、エンドからスタートを引く
「[終了時刻]ー[開始時刻]:[経過時間]」を「[プログラムの位置]経過時間.txt」へ保存する
待機する
【点:浮動小数座標】を、第一横変換する手順 //W1x
0.836 * 点の横 + 0.044 * 点の縦を返す
終わり
【点:浮動小数座標】を、第一縦変換する手順 //W1y
-0.044 * 点の横 + 0.836 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第二横変換する手順 //W2x
-0.141 * 点の横 + 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第二縦変換する手順 //W2y
0.302 * 点の横 + 0.141 * 点の縦 + 0.127を返す
終わり
【点:浮動小数座標】を、第三横変換する手順 //W3x
0.141 * 点の横 – 0.302 * 点の縦を返す
終わり
【点:浮動小数座標】を、第三縦変換する手順 //W3y
0.302 * 点の横 + 0.141 * 点の縦 + 0.169を返す
終わり
【点:浮動小数座標】を、第四横変換する手順 //W4x
0を返す
終わり
【点:浮動小数座標】を、第四縦変換する手順 //W4y
0.175337 * 点の縦を返す
終わり
【回数】だけ【点:浮動小数座標】に、シダを描く手順
//浮動小数座標({0,0})を作って{W1x,W1y}とする
浮動小数座標({0,0})を作って次点とする
もし回数が0より大きければ
点を第一横変換して次点の横とする
点を第一縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし0から10までの乱数が3より小さければ
点を第二横変換して次点の横とする
点を第二縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし終わり
もし0から10までの乱数が3より小さければ
点を第三横変換して次点の横とする
点を第三縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし終わり
もし0から10までの乱数が3より小さければ
点を第四横変換して次点の横とする
点を第四縦変換して次点の縦とする
回数-1だけ次点にシダを描く
もし終わり
そうでなければ
写真にて{点の横*500+200,500-点の縦*500}へCを設定する
もし終わり
終わり
メイン画面とは
ウィンドウを受け継ぐ
+ピクチャー1
はじめの手順
初期化する
ーー貼り付けた部品に対する操作をここに書きます
終わり
初期化する手順
ーー自動生成された手順です。ここに書き加えたプログラムは消える可能性があります
初期化開始する
この実質大きさは{400,530}
この内容は「バーンズリーのシダ」
この文字色は「標準の文字」
ピクチャー1というピクチャーを作る
ピクチャー1を初期化開始する
その位置と大きさは{0,0,400,530}
その文字色は「標準の文字」
そのドッキング方向は「全体」
ピクチャー1を初期化終了する
初期化終了する
この設計スケール比率は{96,96}
終わり
閉じる時の手順
写真を「[プログラムの位置]Fern.png」へ保存する
終わり
終わり
こんにちは。アークです。
処理を見直してコンパイル後の処理時間を3秒にする事ができましたが、
画像が表示されず保存したファイルも白紙状態です。
コンパイルでは下記部分が処理されていない感じです。
写真にて{点の横*500+200,点の縦*500+20}へ緑色を設定する