(基礎プログラミングa 発展テーマ)
ここでは 引数の型(長さの計算をするなら)は 必要に応じてDouble にしておくといい
(整数で扱い切れない値を使うため)
わかりやすい解説のページも参照覧下さい。
時間の都合で本章は説明の時間をとりませんが、
ぜひ各自で探求してみて下さい。
基本的な流れは:
前進
やや右むき
tree(再帰)
やや左向き
tree(再帰)
後退 (最初の場所に戻ってくる)
再帰の時に長さを小さくして呼ぶ 引数がある値より大きい時だけ実行する (Sample では 2つの分枝の比率を変えている)
基本的な動きは
左45°; 前進 ; 右折 ; 前進 ; 左45° // これを(フラクタルの世界では)ジェネレータと呼ぶ
まずはこの動きを関数として名前をつける 例えば cc
lenがある値よりも小さいときは ジェネレータでなく 単なる直進とする
ジェネレータの「前進」の代わりに cc(len/Math.sqrt(2))
// ルート2で割ることになる プログラム例
def cc(len: Double) {
if(len<10) forward(len)
else {
left(45)
cc(len/Math.sqrt(2))
right
cc(len/Math.sqrt(2))
left(45)
}
}
clear ; cc(100)
または
def cc(level: Int) {
if(level<=0) forward(5)
else {
left(45)
cc(level-1)
right
cc(level-1)
left(45)
}
}
clear ; cc(8)
def dragon(level: Int, dr: Int)
のように 引数を2つにする。例:
def rancol:java.awt.Color={color(random(256),random(256),random(256))} //> rancol: java.awt.Color
def dragon(level: Int, dr: Int) {
if(level<=0) forward(5)
else {
turn(45*dr) ; dragon(level-1,1) ; turn(-45*dr)
turn(-45*dr) ; dragon(level-1,-1) ; turn(45*dr)
}
} //> dragon: (level: Int, dr: Int)Unit
clear
for(i<-3 to 10) {
dragon(i,1)
right
setPenColor(rancol)
}
kojoのサンプルにも同様のものがあります。
def koch(len:Double) {
if(len>10) {
val l=len/3;
koch(l) ; left(60)
koch(l) ; right(120)
koch(l) ; left(60)
koch(l)
} else {
forward(len)
}
}
clear
repeat(6) {
koch(200) ; left(60)
}
clear
val sz=5
val sz2=5*Math.sqrt(2)
def peano(level:Int, ang:Int){
if(level>0){
right(ang) ; peano(level-1,-ang)
left(ang) ; forward(sz)
left(ang) ; peano(level-1,-ang)
right(ang)
}else forward(sz2)
}
right
for(l<-1 to 8) {
left(45) ; peano(l,45)
left ; forward(sz2)
left ; peano(l,45)
left ; forward(sz2)
penUp ; forward(Math.pow(2,(l+1)/2)*10)
penDown
}
val sz=5
def shel(level:Int, ang:Int) {
if(level>0) {
left(ang) ; shel(level-1,-ang)
right(ang) ; shel(level-1,ang)
right(ang) ; shel(level-1,-ang)
left(ang) ;
} else forward(sz)
}
right
for(l<-1 to 7) {
shel(l,60)
}
val sz=5
def hil(level:Int,ang:Int) {
if(level>0) {
right(ang)
hil(level-1,-(ang))
forward(sz)
left(ang)
hil(level-1,ang)
forward(sz)
hil(level-1,ang)
left(ang)
forward(sz)
hil(level-1,-(ang))
right(ang)
}
}
for(l<-1 to 5) {
var sz=1000/Math.pow(2,l)
hil(l,90)
Thread.sleep(5000)
}
clear ; hil(5,90)