SICP 2.49

MIT-Schemeだとちょっと想定と違う動きをしてはまった。コードはMIT-Schemeで動くように書いたので、SICP的な正解とは違うかもしれない。

想定と違うところ1

hend.scmだとframe-origin, frame-edge1, frame-edge2がそれぞれorigin-frame, edge1-frame, edge2-frameっていう名前で定義されてる。

想定と違うところ2

2.48の問題文だと線分(segment)は「原点から線分の始点へ向かうベクタと、始点から線分の終点へ向かうベクタで表現できる」と書いてある。でもMIT-Schemeのベクタは「原点から線分の始点へ向かうベクタと、原点から線分の終点へ向かうベクタ」で表現される。
と思ったら誤訳だった。なんだよー。原文はこちら。

A directed line segment in the plane can be represented as a pair of vectors -- the vector
running from the origin to the start-point of the segment, and the vector running from the origin to the endpoint of the segment.

(load "../psets/go.scm")

(define origin-frame frame-origin)
(define edge1-frame frame-edge1)
(define edge2-frame frame-edge2)

; a.
(define (outline frame)
  (let ((origin (origin-frame frame))
        (edge1 (edge1-frame frame))
        (edge2 (edge2-frame frame)))
    (let ((diagonal (sub-vect (add-vect edge1 edge2) origin)))
      (segments->painter (list (make-segment origin edge1)
                               (make-segment origin edge2)
                               (make-segment edge1 diagonal)
                               (make-segment edge2 diagonal))))))

; b.
(define (diagonal-line frame)
  (let ((origin (origin-frame frame))
        (edge1 (edge1-frame frame))
        (edge2 (edge2-frame frame)))
    (let ((diagonal (sub-vect (add-vect edge1 edge2) origin)))
      (segments->painter (list (make-segment origin diagonal)
                               (make-segment edge1 edge2))))))

; c.
(define (medians frame)
  (define (midpoint v1 v2)
    (scale-vect 0.5 (add-vect v1 v2)))
  (let ((origin (origin-frame frame))
        (edge1 (edge1-frame frame))
        (edge2 (edge2-frame frame)))
    (let ((diagonal (sub-vect (add-vect edge1 edge2) origin)))
      (let ((origin-edge1 (midpoint origin edge1))
            (origin-edge2 (midpoint origin edge2))
            (edge1-diagonal (midpoint edge1 diagonal))
            (edge2-diagonal (midpoint edge2 diagonal)))
        (segments->painter (list (make-segment origin-edge1 origin-edge2)
                                 (make-segment origin-edge2 edge2-diagonal)
                                 (make-segment edge2-diagonal edge1-diagonal)
                                 (make-segment edge1-diagonal origin-edge1)))))))

; dは省略

; test
(define f1 (make-frame (make-vect 0.1 0.1)
                       (make-vect 0.2 0.3)
                       (make-vect 0.6 0.2)))
(paint-g1 (outline f1))
(paint-g1 (diagonal-line f1))
(paint-g1 (medians f1))

実行結果。上からa, b, cと並んでいる。