本体資料

メディアプログラミング演習―第9回(第3テーマ3日目)―
再帰的アルゴリズム:再帰図形とフラクタル図形
再帰関数を用いて,繰り返しのある平面図形を描く.
最初の簡単な例を示す.図1は,円の中に,半径が半分の円を繰り返し描いた図形であ
る.これを実現する再帰プログラムは,図2となる(maru-pro).
void draw(){
Maru(5,250, 250, 200);
}
void Maru(int n, float x, float y, float r) {
ellipse(x, y, r*2, r*2);
if (n>1) {
float R = r/2;
Maru(n-1, x+R, y, R); //右側の円
Maru(n-1, x-R, y, R); //左側の円
}
}
図1 円の繰り返し
図2.図1を描くプログラム
図形例1:次いで,図3の図形を「再帰的に」描くことを考える.
図3 最初の図形
図4.基本図形
この図形は,図4のような Y 字図形を描く手続きを再帰的に①~③に適用すること
で描ける.プログラムは,以下の通りである.
void draw(){
drawfig1(5, 200.0, 500.0,500.0);
}
void drawfig1(int n, float leng,float XO,float YO) {
float x, y, ang;
if (n == 0) {return;};
float[] rx,ry;
rx=new float[3]; ry=new float[3];
drawfig1(n - 1, leng, rx[0], ry[0]);
for(int k=0;k<3;k++)
drawfig1(n - 1, leng, rx[1], ry[1]);
drawfig1(n - 1, leng, rx[2], ry[2]);
{ ang=3.141592/180*k*120;
rx[k] = leng*sin(ang) + XO;
(A)
}
ry[k] = leng*cos(ang) + YO;
line(XO,YO,rx[k],ry[k]);
};
図5.図3を描くプログラム
上図(A)は,図4の周囲3点の座標を求めるとともに,中心から各点への線分を描
いている.繰り返し数nが0でなければ,①~③の各頂点にて同じことを繰り返す(
(B)
の部分)
(lattice-pro).
図形例2:例1を発展させると,次のような図6も描ける.図6は,図7のような5分
木線分の各頂点で,長さを変えて再帰的に描いた図形である(penta-pro).
図6
繰り返し図形2
図7
図6の基本図形
応用図形(宿題,レポート):図8および図9を描きなさい
図8
図1の応用
図9
図6の応用
(B)
フラクタル図形
フラクタル(フランス語: fractale)は、フランスの数学者ブノワ・マンデルブロが
導入した幾何学の概念である.フラクタル(Fractal)図形とは、自己相似性を持つ形
状でどの一部分を取り出しても全体と相似の関係をもち,有名な例では,マンデルブロ
ウ集合,ジュリア集合,コッホ曲線,シェルピンスキー曲線などがある.フラクタル図
形のなかには,再帰図形が多く含まれている.以下では,それらを作成する.
① コッホ曲線は,有名でありここでは,プログラムの添付する(koch-pro).
② 樹木曲線もほぼ同様の方法で描くことができる(tree-pro).
添付付プログラムは,
Processing の座標系で描いているので,「木」が横になっている,
これら2つのプログラムの構造や流れは,ほぼ同じである.これらを理解した上で,次
は,自作することにする.
③ シェルピンスキーのギャスケット(英: Sierpinski gasket)はフラクタル図形の 1
種であり、自己相似的な無数の三角形からなる図形である。その名前は,ポーラン
ドの数学者ヴァツワフ・シェルピンスキに由来する。
シェルピンスキーのギャスケットはフラクタル図形であり、以下の手順を繰り返すこ
とで、近似的に作図できる。
A) 1 辺の長さが 1 の正三角形の各辺の中点を互いに結ぶと、中心部に 1 辺の長さ
が 1/2 の正三角形ができる。
B) この 1 辺の長さが 1/2 の正三角形を切り取る。
C) これによって、1 辺の長さが 1/2 の正三角形が 3 個残る。
D) さらに、これら 3 つの正三角形の各辺の中点を互いに結んで出来た長さが 1/4
の正三角形を切り取る。
「切り取る」のではなく「その三角形を描く」として7回繰り返すと図10となる.
図10
シェルピンスキーのギャスケット
図11
その基本手順
さて,これを再帰的に描く方法は以下の通りである.描く関数を
void triangle(int lev, float r, float x, float y)
とする.
構造や流れは,前述の例と同じであるが,変数 lev は,繰り返しの上限とする.
* これが0である場合は,それ以上繰り返さないので,
―>
(x,y)を上頂点として,長さrの正三角形を描く.
* そうでない場合,
―>
図9の①~③を頂点とし,辺の長さを半分にし,この関数を再帰的の呼
び出す
このプログラムの雛形は以下の通りであり,sierpin-pro にある.
void triangle(int lev,float r, float x,float y)
{
if( lev==0){
::::::
<=
頂点(x,y) 一辺がrの正三角形を描く
}
else
{
:::::
<=図9の①~③を頂点とし長さ r/2 で再帰する
}
}
ヒント:
(A)三角形の3点は,(x,y) ,( x-r*sth,y+r*cth), (x+r*sth,y+r*cth)である.
(B)
②,③の座標は,各々(x-r/2*sth,y+r/2*cth ),(x+r/2*sth,y+r/2*cth )
である.
Ex.完成させ,レポートとして提出しなさい.