画像の解釈は正しいです。画像は、原点(0、0)が左下隅、(1、1)が右上隅である単位正方形の線分で構成されています。
画家は、質問で与えられた変換を使用して、画像をフレームにマッピングします。上のeinsten
画像はデフォルトのフレーム(単位正方形)で描画されているため、正常に表示されます。
SICP Picture Languageを使用して、次の3つのステップで画像を作成および表示できます。
- 線分のリストを定義する
- それらの線分からセグメントペインタを作成します
- 新しいセグメントペインターでペイントを呼び出す
私はブログ投稿SICP2.49:プリミティブペインターの定義によるいくつかの簡単な画像でこれを行います。2つの線分だけを使用した簡単な例を次に示します。
; The painter that draws an 'X' by connecting opposite corners of the frame.
(define x-segments
(list
(make-segment
(make-vect 0.0 0.0)
(make-vect 0.99 0.99))
(make-segment
(make-vect 0.0 0.99)
(make-vect 0.99 0.0))))
(define x-painter (segments->painter x-segments))
(paint x-painter)
DrRacketで最後のコマンドを実行したときの結果は次のとおりです。
画像を描画するための新しいフレームを作成することで、画像を反転および回転させることができます。
フレームは次の3つのベクトルで定義されます。
テキスト(ペインターの変換と結合というタイトルのセクション)に示されているtransform-painter
関数を使用して、新しい原点とエッジを使用して既存のセグメントペインターを変換できます。
(define (transform-painter painter origin corner1 corner2)
(lambda (frame)
(let ((m (frame-coord-map frame)))
(let ((new-origin (m origin)))
(painter
(make-frame new-origin
(sub-vect (m corner1) new-origin)
(sub-vect (m corner2) new-origin)))))))
たとえば、左に45度回転した元のアインシュタイン画像を描画する場合は、einstein
セグメントペインタを新しい原点、下端、左エッジとともに渡すだけでtransform-painter
、新しいセグメントペインタが返されます。つまり、transform-painter
画像の左下、右下、左上隅を描画する場所を指定する必要があります。これにより、元のセグメントペインタですべての線分が変換されます。
; rotate an image 45 degrees to the left
(define (rotate-45 painter)
((transform-painter (make-vect 0.5 0.0)
(make-vect 1.0 0.5)
(make-vect 0.0 0.5))
painter))
コマンドを実行して(paint (rotate-45 einstein))
、回転した画像を表示できます。