技術士試験の平成27年度情報工学部門に出題されたコッホ曲線を Pharo で実装してみます。
Pharo を使用するのはグラフィックス周りの実装が楽だからです。
BorderedMorph subclass: #KochMorph instanceVariableNames: 'location angle' classVariableNames: '' package: 'PBE-Fractal'
まずは KochMorph オブジェクトを作ります。
KochMorph は、BorderedMorph のサブクラスにします。これで BorderedMorph の性質を継承しました。
インスタンス変数は location と angle を用意します。
次にインスタンス変数のアクセッサを用意します。プロトコルは accessing が適切です。
KochMorph>>angle (accessing) angle ^ angle
KochMorph>>location (accessing) location ^ location
解説はいらないでしょう。
設定する方は private プロトコルに実装します。
KochMorph>>angle: (private) angle: radian angle := radian
KochMorph>>location: (private) location: point location := point
次。初期化メソッドをオーバーライドします。*1
KochMorph>>initialize (initializing) initialize super initialize. self extent: 800 @ 300. self location: 100 @ 200. self angle: 0. self drawKoch: 100
initialize メソッドをオーバーライドする時は、
最初に super initialize するのを必ず忘れないようにします。
忘れると大変な事が起こります! どう大変になるかは恐ろしくて書けませんw
自身のモーフの大きさ設定、インスタンス変数の初期化をします。
ついでに、面倒なのでコッホ曲線の描画もしてしまいます。(手抜き)
さていよいよ本丸のメソッドを書いていきます。
前進するメソッドから。
KochMorph>>forward: (drawing) forward: amountOfMovement | x y newLocation | x := angle cos * amountOfMovement. y := angle sin * amountOfMovement. newLocation := x @ y translateBy: self location . self addMorph: (LineMorph from: self location to: newLocation color: Color yellow width: 2). self location: newLocation
angle から移動先のポイントを計算して LineMorph をサブモーフに追加します。
次に方向転換するメソッド。
KochMorph>>turnLeft: (drawing) turnLeft: degree self angle: self angle - (2 * Float pi * degree / 360)
left: メソッドは上位階層オブジェクトで実装されているので、これをオーバーライドはしたくないので、turnLeft: メソッドにします。
引数は角度(60度とか)ですが、angle はラジアンで持ちたいので変換しています。
次はコッホ曲線を書くメソッドです。
KochMorph>>drawKoch: (drawing) drawKoch: n | nn | n > 7 ifTrue: [ nn := n / 3. self drawKoch: nn. self turnLeft: 60. self drawKoch: nn. self turnLeft: -120. self drawKoch: nn. self turnLeft: 60. self drawKoch: nn ] ifFalse: [ self forward: 20 ]
これも draw: はオーバーライドしたくないので避けます。
はい。以上で実装は完了です。
Playground (Workspace) を開いて、以下を do-it します。
KochMorph new openInWorld
こんなのが表示されれば OK です。
Pharo ならグラフィック周りの実装がちょー簡単です。
面倒くさい事を考える必要は何も無いです。素晴らしいね!
OOPバンザーイ!