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
のように指定する。

樹木曲線とは

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

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

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

0142: /**
0143:  * 樹木曲線メインプログラム
0144:  * @param   object $img  イメージストリーム
0145:  * @param   int    $n    再帰の深さ
0146:  * @param   double $len  枝の長さ
0147:  * @param   double $angle枝の傾き(ラジアン)
0148:  * @param   int    $length    1辺の長さ
0149:  * @param   int    $pen_colorペンの色
0150:  * @return  -
0151: */
0152: function tree($img$n$len$angle$length$pen_color) {
0153:     static $fac  = 0.7;
0154:     static $turn = 0.5;
0155: 
0156:     $dx = $len * sin($angle);
0157:     $dy = $len * cos($angle);
0158:     movePen($img$dx$dyTRUE$length$pen_color);
0159:     if ($n > 0) {
0160:         tree($img$n - 1, $len * $fac$angle + $turn$length$pen_color);
0161:         tree($img$n - 1, $len * $fac$angle - $turn$length$pen_color);
0162:     }
0163:     movePen($img, 0 - $dx, 0 - $dyFALSE$length$pen_color);
0164: }

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

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

0125: /**
0126:  * ペンを移動する(プロッタのエミュレータ)
0127:  * @param   object $img  イメージストリーム
0128:  * @param   float  $dx, $dyペンの移動量
0129:  * @param   bool   $draw TRUE=ペンを落として移動/FALSE=ペンを上げて移動
0130:  * @param   int    $length    1辺の長さ
0131:  * @param   int    $pen_colorペンの色
0132:  * @return  -
0133: */
0134: function movePen($img$dx$dy$draw$length$pen_color) {
0135:     static $x$y;
0136: 
0137:     if ($draw == TRUE)  my_imageline($img$x$y$x + $dx$y + $dy$length$pen_color);
0138:     $x += $dx;
0139:     $y += $dy;
0140: }

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

参考サイト

(この項おわり)
header