PHPで樹木曲線を描く

(1/1)
PHPで樹木曲線を描くプログラムを作る。
樹木曲線はフラクタル図形の一種で、再帰呼び出しを使うと簡単に描くことができる。

(2022年4月3日)PHP8対応,大幅改訂

サンプル・プログラムの実行例

PHPで樹木曲線を描く

サンプル・プログラム

圧縮ファイルの内容
TreeCurve.phpサンプル・プログラム本体
ダウンロードしたスクリプトを実行するには GDライブラリが必要である。
なお、コマンドラインから枝の数(order;2以上20以下の整数)と描画領域の1辺の長さ(length;100以上3000以下の整数)を指定できるようにしてある。たとえば、枝の数が12で、描画領域の1辺を600(ドット)としたければ
TreeCurve.php?order=12&length=600
のように指定する。

樹木曲線とは

樹木曲線フラクタル図形の一種である。
フラクタル図形とは、その図形を拡大していくと、ある部分に元の図形と同じパターンが現れるものである。海岸線や雪の結晶など、自然界でよく見られる。

樹木曲線は左図のような図形である。枝の部分を切り出して拡大すると、元の枝と同じパターンになっていることが分かる。

サンプル・プログラムの解説:樹木曲線

 142: /**
 143:  * 樹木曲線メインプログラム
 144:  * @param   object $img  イメージストリーム
 145:  * @param   int    $n    再帰の深さ
 146:  * @param   double $len  枝の長さ
 147:  * @param   double $angle 枝の傾き(ラジアン)
 148:  * @param   int    $length    1辺の長さ
 149:  * @param   int    $pen_color ペンの色
 150:  * @return  -
 151: */
 152: function tree($img, $n, $len, $angle, $length, $pen_color) {
 153:     static $fac  = 0.7;
 154:     static $turn = 0.5;
 155: 
 156:     $dx = $len * sin($angle);
 157:     $dy = $len * cos($angle);
 158:     movePen($img, $dx, $dy, TRUE, $length, $pen_color);
 159:     if ($n > 0) {
 160:         tree($img, $n - 1, $len * $fac, $angle + $turn, $length, $pen_color);
 161:         tree($img, $n - 1, $len * $fac, $angle - $turn, $length, $pen_color);
 162:     }
 163:     movePen($img, 0 - $dx, 0 - $dy, FALSE, $length, $pen_color);
 164: }

樹木曲線を描く部分はシンプルである。
ユーザー関数 tree再帰呼び出ししている。

解説:プロッタ・エミュレータ

 125: /**
 126:  * ペンを移動する(プロッタのエミュレータ)
 127:  * @param   object $img  イメージストリーム
 128:  * @param   float  $dx, $dy ペンの移動量
 129:  * @param   bool   $draw TRUE=ペンを落として移動/FALSE=ペンを上げて移動
 130:  * @param   int    $length    1辺の長さ
 131:  * @param   int    $pen_color ペンの色
 132:  * @return  -
 133: */
 134: function movePen($img, $dx, $dy, $draw, $length, $pen_color) {
 135:     static $x, $y;
 136: 
 137:     if ($draw == TRUE)  my_imageline($img, $x, $y, $x + $dx, $y + $dy, $length, $pen_color);
 138:     $x +$dx;
 139:     $y +$dy;
 140: }

再帰呼び出しを用いて図形を描く場合、現在の位置から横方向(X方向)へ幾ら、縦方向(Y方向)へ幾ら進むといった相対座標指定を使うことが多い。プロッタではこのような制御を行うことが多い。
そこで今回は、プロッタのように相対座標で線分を描くためのユーザー関数 movePen を用意した。

参考サイト

(この項おわり)
header