SICP 問題 2.51(ペインタの合成)

ご無沙汰しちゃった。。仕事でヘマしてダウナーになっちまったのと、そのあと元気になったけど、休みの日にモデルハウスにひやかしにいったら家を建てたくなっちゃって間取りとか考えすぎちゃって、SICPから離れてしまった。。
一ヶ月ぶりに復帰だ!

問題

ペインタに対して below 演算を定義せよ。below は引数として2つのペインタをとる。結果のペインタはフレームを貰うと第1のペインタでフレームの下に描き、第2のペインタで上に描く。below を二つの異なった方法で ── まず上のbeside に似た方法で、次に beside と(問題2.50)の適切な回転演算を使って ── 定義せよ。

解答

まずは拙ブログの「SICP §2.2.4(図形言語 その?)」で記述しておいた beside と同じような実装を。

(define (below painter1 painter2)
  (let ((down (transform-painter painter1
				(make-vect 0.0 0.0)
				(make-vect 1.0 0.0)
				(make-vect 0.0 0.5)))
	(up (transform-painter painter2
			      (make-vect 0.0 0.5)
			      (make-vect 1.0 0.5)
			      (make-vect 0.0 1.0))))
    (lambda (frame)
      (down frame)
      (up frame))))

前エントリと同様、この変換手続きを painter.scm に追記し、main.scm の呼び出し箇所を変更してみる。
では実験。

((below house diamond) frame) その1



次に beside と回転を使った変換を定義してみる。

(define (below painter1 painter2)
  ;いずれにしても二つのペインタは変換が必要なのでやっちゃう。
  (let ((left (transform-painter painter1
				(make-vect 0.0 1.0)
				(make-vect 0.0 0.0)
				(make-vect 1.0 1.0)))
	(right (transform-painter painter2
				 (make-vect 0.5 1.0)
				 (make-vect 0.5 0.0)
				 (make-vect 1.0 1.0))))
    ;生成したペインタを beside に渡し、
    ;更に rotate90 を使って反時計回りに90度変換!
    (rotate90 (beside left right))))

同じく painter.scm に追記して、ロード時に上書きされるようにしてみて実験。

((below house diamond) frame) その2


おっけ〜♪