ピラミッドのソース

暇なので書きましたw
まず始めに以前に書いた KochMorph のコードを再利用したいのでリファクタリングから行います。
FractalMorph
FractalMorph は図形を描画するための基本的なメソッドを実装します。
FractalMorph は BorderedMorph のサブクラスにします。インスタンス変数は、location と angle を持ちます。

BorderedMorph subclass: #FractalMorph
	instanceVariableNames: 'location angle'
	classVariableNames: ''
	package: 'PBE-Fractal'

インスタンス変数をアクセスするメソッドから。accesing プロトコルに書きます。

angle
	^ angle
location
	^ location

インスタンス変数を設定するメソッドは protected プロトコルに書きます。
Smalltalk ではメソッドのアクセス制限は無いのですが、protected プロトコルに書くことで、
このオブジェクトとサブオブジェクト群からのアクセスのみを推奨している事をコードを読む人に伝えます。

angle: radian
	angle := radian
location: point
	location := point

次は初期化メソッドです。初期化メソッドは initialization プロトコルに書きます。
initialize メソッドはオーバーライドするので最初に「super initialize」が必要です。これを絶対に忘れないでください。

initialize
	super initialize.
	self angle: 0.
	self location: self center

最後は描画を行うためのメソッドです。drawing プロトコルに書きます。
また、turnLeft: メソッドは turnRight: メソッドを使って書きます。

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
turnLeft: degree
	self turnRight: degree negated
turnRight: degree
	self angle: self angle + (2 * Float pi * degree / 360)

以上です。
FractalMorph は具体的に描画を行うメソッドは持たないので、なにも図形を描画できません。
具体的に描画を行うメソッドはサブオブジェクトで実装します。

KochMorph
以前に実装した KochMorph から実装します。
KochMorph は FractalMorph のサブオブジェクトにします。

FractalMorph subclass: #KochMorph
	instanceVariableNames: ''
	classVariableNames: ''
	package: 'PBE-Fractal'

次に初期化メソッドです。initialization プロトコルに書きます。
オーバーライドするので、最初に super initialize を書きます。

initialize
	super initialize.
	self extent: 800 @ 300.
	self location: 100 @ 200.
	self drawKoch: 100

コッホ曲線を描画するメソッドを実装します。プロトコルは 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 ]

以上です。
ここまで実装したら、Playground で

KochMorph new openInWorld

と打ち込み do it するとコッホ曲線を描画するモーフを表示します。
TriangleMorph
さて本丸のオブジェクト TriangleMorph です。これも FractalMorph のサブオブジェクトにします。
また、描画する三角形の一辺の長さを持つインスタンス変数 lengthOfSide を持ちます。

FractalMorph subclass: #TriangleMorph
	instanceVariableNames: 'lengthOfSide'
	classVariableNames: ''
	package: 'PBE-Fractal'

インスタンス変数をアクセスするメソッドを用意します。accesing プロトコルに書きます。
三角形の高さ、三角形の一辺の半分を求めるメソッドも用意しておきます。

lengthOfSide
	^ lengthOfSide
heightOfTriangle
	^ (self halfLengthOfSide * 3 sqrt) rounded
halfLengthOfSide
	^(self lengthOfSide / 2) rounded

インスタンス変数を設定するメソッドは private プロトコルに書きます。
Smalltalk ではアクセス制限は無いのですが、private プロトコルにすることで、
このメソッドはこのオブジェクト内からのみの呼び出しを推奨していることをコードを読む人に伝えます。
最近の Pharo では private プロトコルにあるメソッドを外部のオブジェクトから呼び出すと警告を受けるかも知れません。(そういう悪い事したことないのでわかりませんw)

lengthOfSide: newLength
	lengthOfSide := newLength

初期化メソッドです。initialization プロトコルに書きます。
しつこいようですが重要な事なので書きます。
オーバーライドするメソッドなので最初に super initialize を書くのを忘れずに。
モーフの大きさ設定は手抜きなので、大きなピラミッドを描画したい場合は適宜変更してください。

initialize
	super initialize.
	self extent: 800 @ 800.
	self location: self center x @ 100.
	self lengthOfSide: 100.
	self drawTriangleRec1: self stepOfTriangles top: self location

定数を返すメソッドを書きます。constants プロトコルに書きます。
コード中にマジックナンバーを書くのは推奨されないため、定数を返すメソッドとして実装するのが良いでしょう。
このメソッドはピラミッドの段数を持ちます。5 となっているので 5 段のピラミッドを描画します。

stepOfTriangles
	^5

最後に三角形を描画するメソッドです。drawing プロトコルに書きます。
drawTriangle: は一辺の長さが self lengthOfSide の正三角形を1つ描画します。

drawTriangle: topPoint
	self angle: 0.
	self location: topPoint.
	self turnRight: 60.
	self forward: self lengthOfSide.
	self turnRight: 120.
	self forward: self lengthOfSide.
	self turnRight: 120.
	self forward: self lengthOfSide

drawTriangleRec1: top: および drawTriangleRec2: top: は再帰的に三角形を描画することでピラミッドを作ります。
再帰するメソッドはバグって無限ループになると大変な事になるため、イメージを保存してから実行するようにしましょう。一生懸命書いたコードが失われてしまう事があります。

drawTriangleRec1: row top: aPoint 
	row = 0
		ifTrue: [ ^self ].
	self drawTriangleRec2: row top: aPoint.
	self drawTriangleRec1: row - 1 top: (aPoint x + self halfLengthOfSide) @ (aPoint y + self heightOfTriangle)
drawTriangleRec2: row top: aPoint 
	row = 0
		ifTrue: [ ^self ].
	self drawTriangle: aPoint.
	self drawTriangleRec2: row - 1 top: (aPoint x - self halfLengthOfSide) @ (aPoint y + self heightOfTriangle)

以上です。
Playground に

TriangleMorph new openInWorld

と入力して do it すると三角形のピラミッドを描画するモーフが現れます。