SICP 연습문제 2.49 친절한 풀이

문제

segments->painter를 써서, 다음과 같은 기본 페인터를 정의하라.

a. 그림틀의 테두리를 그려주는 페인터
b. 그림틀에서 마주보는 곡짓점을 서로 연결하여 'X’를 그리는 페인터
c. 그림틀의 모서리 가운데 점 네 개를 연결하여 다이아몬드 꼴을 그리는 페인터
d. wave 페인터

문제로 부터 얻은 것

소모한 시간에 비해 얻는 것이 많이 없는 문제였습니다.
처음 문제를 풀 때, segments->painter가 기본으로 구현되어 있는지 몰라서 많이 해맸습니다.
또 segments->painter가 1.0을 최대의 값으로 가진다는 것도 몰라서 다른 풀이들을 봐도 이해가 안되었습니다.
막상 풀고 나니 그렇게 얻은 것은 없는 문제였습니다.

문제풀이

이 문제를 풀기 위해서는, 책에 있는 segments->painter 프로시저를 그대로 사용하면 안됩니다. scheme의 sicp 패키지에는 자체에 내장된 segments->painter와 vect, segment가 있으니 이를 활용해야 합니다.

#lang sicp 
(#%require sicp-pict)

내장된 프로시저 segments->painter는, 그리고자 하는 선분의 x값과 y값의 최대치가 1.0인 선분을 그릴 수 있습니다. 다시말해, 선분의 좌표가 1.0을 넘어가면 더이상 그리지 않습니다.

a. 그림틀의 테두리를 그려주는 페인터

그림틀의 테두리의 길이는 1로 고정되어 있습니다. 그러니 원점에서 수직 수평으로 뻗은 두 선분과, 각 끝에서 (1,1)로 뻗은 두 선분을 그려주면 됩니다.

(define outline 
(segments->painter
(list
(segment (vect 0.0 0.0) (vect 0.0 1.0))
(segment (vect 0.0 0.0) (vect 1.0 0.0))
(segment (vect 0.0 1.0) (vect 1.0 1.0))
(segment (vect 1.0 0.0) (vect 1.0 1.0)))))

b. 그림틀에서 마주보는 꼭짓점을 서로 연결하여 'X’를 그리는 페인터

각 대각선의 좌표를 연결해주면 구할 수 있습니다.

(define X 
(segments->painter
(list
(segment (vect 0.0 0.0) (vect 1.0 1.0))
(segment (vect 0.0 1.0) (vect 1.0 0.0)))))

c. 그림틀의 모서리 가운데 점 네 개를 연결하여 다이아몬드 꼴을 그리는 페인터

(define diamond
(segments->painter
(list
(segment (vect 0.5 0.0) (vect 1.0 0.5))
(segment (vect 1.0 0.5) (vect 0.5 1.0))
(segment (vect 0.5 1.0) (vect 0.0 0.5))
(segment (vect 0.0 0.5) (vect 0.5 0.0)))))

d. wave 페인터

과연 wave를 하나 하나 그리는 것이 컴퓨터의 구조와 해석을 공부하는 데에 도움이 될까하는 의문이 들었습니다. 그냥 인터넷에 떠도는 wave를 퍼왔습니다.

(define wave
(segments->painter
(list (segment (vect .25 0) (vect .35 .5))
(segment (vect .35 .5) (vect .3 .6))
(segment (vect .3 .6) (vect .15 .4))
(segment (vect .15 .4) (vect 0 .65))
(segment (vect 0 .65) (vect 0 .85))
(segment (vect 0 .85) (vect .15 .6))
(segment (vect .15 .6) (vect .3 .65))
(segment (vect .3 .65) (vect .4 .65))
(segment (vect .4 .65) (vect .35 .85))
(segment (vect .35 .85) (vect .4 1))
(segment (vect .4 1) (vect .6 1))
(segment (vect .6 1) (vect .65 .85))
(segment (vect .65 .85) (vect .6 .65))
(segment (vect .6 .65) (vect .75 .65))
(segment (vect .75 .65) (vect 1 .35))
(segment (vect 1 .35) (vect 1 .15))
(segment (vect 1 .15) (vect .6 .45))
(segment (vect .6 .45) (vect .75 0))
(segment (vect .75 0) (vect .6 0))
(segment (vect .6 0) (vect .5 .3))
(segment (vect .5 .3) (vect .4 0))
(segment (vect .4 0) (vect .25 0)))))

e. painter 테스트

지금까지 만든 프로시저들이 잘 작동하는지 테스트 코드를 실행시켜 보겠습니다. paint-square는 4개의 그림을 하나의 그림틀에 그리는 프로시저입니다.

(define (paint-square p1 p2 p3 p4)
(paint (below (beside p3 p4)
(beside p1 p2))))


(paint-square outline X diamond wave)

테두리, 대각선, 마름모, 웨이브의 순서로 그려진 그림



읽어주셔서 감사합니다.