Structure and Interpretation of Computer Programs: Assignment 3 Seung-Hoon Na October 4, 2018 1 George (아래 3개의 문제에 대한 구현이 모두 포함된 george.rkt파일을 제출하시오. 실행후 Problem 1.3에 대한 Display결과가 나와야 함) George 그림은 다음과 같이 17여개의 선분으로 구성된다. 위의 George그림의 구성요소인 선분 (segments)들을 george-lines로 정의하는 scheme code는 다음과 같다. 이때, 선분들의 위치 (coordinates)는 George가 단 위 사각형상에 사상되었을때의 위치이다 (전체 코드는 강의 웹의 george-lines.rkt 파일을 참조할 것). ( require racket/gui/base ) ( require racket/draw ) ; vector ( make-vect x y) ( cons x y)) ( xcor vect ) ( car vect )) ( ycor vect ) ( cdr vect )) ; segment ( make-segment p1 p2 ) ( cons p1 p2 )) ( start-segment seg ) ( car seg )) ( end-segment seg ) ( cdr seg )) ; george-vects 1
;... p1 p2 p3 p4 ( make-vect ( make-vect ( make-vect ( make-vect.25 0) ).35.5) ).3.6) ).15.4) ) ; george-lines george-lines ( list ( make-segment p1 p2 ) ( make-segment p2 p3 ) ( make-segment p3 p4 ) ; ;... )) 1.1 Problem 1: make-picture 구현 Picture는 프레임 (frame)을 인자 (argument)로 취하고 해당 프레임의 사이즈에 맞 게 주어진 그림의 구성요소 (선분 또는 곡선 등)를 그리는 프로시저 (procedure) 로 정의된다. 앞서의 George그림과 같이 선분들로 구성된 picture를 생성하는 make-picture 함수를 구현하시오. ( make-picture seglist ) ( lambda ( rect ) ;... Note: make-picture를 test하기 위한 절차는 다음과 같다. 1. 위의 make-picture를 호출하여 george-lines으로부터 george를 다음과 같이 정의한다 george ( make-picture george-lines )) 2. 그림이 display되는 frame1을 다음과 같이 정의한다. ; rect origin x-axis y-axis frame1 ( make-vect 0 0) ) ( make-vect 730 0) ) ( make-vect 0 730) ) ( make-rectangle origin x-axis y-axis )) ( make-vect과 make-rectangle은 교과서의 내용 참조). 3. 다음을 수행하여 george를 frame1에 display한다. frame ( new frame% [ label " Paint Triangle "] [ width 747] [ height 769]) ) canvas ( new canvas% [ parent frame ] [ paint-callback ( lambda ( cnavas dc ) ( send dc set-pen red-pen ) ( send dc set-brush no-brush ) ( on-paint )) ]) ) red-pen ( make-object pen% " RED " 2 ' solid )) 2
no-brush ( make-object brush% " BLACK " ' transparent )) dc ( send canvas get-dc )) ; DEFINE CALLBACK PAINT PROCEDURE (define (on-paint) (george frame1)) ; MAKING THE FRAME VISIBLE ( send frame show #t) 1.2 Problem 2: screen-transform Problem 1의 George를 출력하면 다음과 같이 뒤집어진 형태로 화면에 display 된다. 이렇게 뒤집힌 이유는 화면 좌표계가 일반 좌표계와 달리, 원점이 좌상단이고, 이에 x축은 우측방향, y축은 아래쪽 방향을 가리키기 때문이다. 화면 좌표계와 일반 좌표계의 차이를 고려하여, 주어진 picture가 정상적으로 display될 수 있도록 다음 screen-transform를 정의하고 필요한 procedures를 모두 구현하시오. ( screen-transform pict ) ( ( lambda rect ) ( rotate180 ( flip pict )))) 추가로 위의 screen-transform를 적용하여 George를 화면에 display하는 code 를 작성하시오. 1.3 Problem 3: square-limit 강의 slide에서 소개된 바와 같이, square-limit는 다음과 같이 정의된다. ; square-limit ( square-limit pict n) (4 same ( conner-push pict n) 1 2 4 3) ) 또한, george-squarelimit은 다음과 같다. george-squarelimit ( square-limit 4 bats 2) ) 위의 george-squarelimit가 다음과 같이 display되도록 해당 코드를 작성하여 제출하시오. (george-lines.rkt내용을 포함하여 George와 관련된 Problem 1-3내용 모두 포함되도록 file을 하나로 만들어서 제출할 것) 3
2 Fish (아래 6개의 문제에 대한 구현이 모두 포함된 fish.rkt파일을 제출하시오. 실행 후에 Problem 2.6에 대한 Display결과가 나와야 함 ) 예셔의 Fish그림을 근사적으로 재현하기 위해 다음 30여개의 Bezier Curves 들로 구성된 Fish조각을 가정하자. 위의 Fish그림의 구성요소인 곡선 (surves)들을 fish-curves로 정의하는 scheme code는 다음과 같다. (전체 코드는 강의 웹의 fish-curves.rkt파일을 참조하시오) ( require racket/gui/base ) ( require racket/draw ) ; curves ( make-curve p1 p2 p3 p4 ) ( list p1 p2 p3 p4 )) ( start-curve cur ) ( car cur )) ( control-curve cur ) ( cadr cur )) (2 nd-control-curve cur ) ( caddr cur )) ( end-curve cur ) ( cadddr cur )) ; ;;; points... ; ;;; The fish ' s curves 4
fish-curves ( list ( make-curve p1 p2 p3 p4 ) ( make-curve p5 p6 p7 p8 ) ( make-curve p9 p10 p11 p12 ) ( make-curve p13 p14 p15 p16 ) ( make-curve p17 p18 p19 p20 ) ( make-curve p21 p22 p23 p24 ) ; ;;; 2.1 Problem 1: make-picture-from-curve 앞서의 Fish그림과 같이 곡선(curves)들로 구성된 picture를 생성하는 make-picture-from-curve 함수를 구현하시오. ( make-picture-from-curve curvelist ) 추가로, George그림 경우와 마찬가지로 Fish이 display되는지 확인해보시오. 2.2 Problem 2: rotate, above-rotate45 아래에 제시된 변환들을 구현하고자 한다. 1. 위 그림처럼 일반좌표계에서 주어진 picture를 반시계방향으로 angle만큼 회전하는 rotate를 구현하시오. ( rotate pict angle ) ( lambda ( rect )... 특수한 경우로, angle이 90도 (= π/2)인 경우는 강의노트의 rotate90와 같아 지도록 구현할 것. ( rotate90 pict ) ( rotate pict (* 0.5 pi ))) 5
2. 위 그림처럼, 일반좌표계에서 주어진 picture를 반시계방향으로 45도만큼 회 전한 후, 프레임의 x-y대각선이 원래 프레임의 상변과 일치하도록 길이를 2 만큼 축소하고 원점을 조정한 above-rotate45를 구현하시오. ( above-rotate45 pict ) ( lambda ( rect )... 2.3 Problem 3: Fish tile 테스트 다음과 같이 fish조각을 4개 조합하여 fish-tile을 정의한 후 display해보시오. (필요 한 함수는 모두 구현할 것) ; together4 ( together4 pict1 pict2 pict3 pict4 ) ( lambda ( rect ) ( pict1 rect ) ( pict2 rect ) ( pict3 rect ) ( pict4 rect ))) fish ( make-picture-from-curve fish-curves )) fish2 fish3 fish4 fish5 ( flip ( above-rotate45 fish ))) ( rotate fish2 (* 0.5 pi ))) ( rotate fish2 (* 1.0 pi ))) ( rotate fish2 (* 1.5 pi ))) fish-tile ( together4 fish2 fish3 fish4 fish5 )) fish-tile를 display가 다음 그림처럼 나오는지 확인해볼 것. 2.4 Problem 4: quardtet, nonet구현 다음 그림과 같이 quardtet는 주어진 프레임을 4등분하여 4개의 부분 그림을 각각 배치하는 프로시저이고, nonet는 9등분하여 9개의 그림을 각각 배치하는 프로시저 6
이다. quardtet와 nonet를 구현시오. (beside, above를 사용할 것) ( quardtet p q r s)... ( nonet p q r s t u v w x)... 2.5 Problem 5: side-push, corner-push구현 및 테스트 아래의 정의에 따라 quardtet을 이용하여 side-push, corner-push 를 구현하시오. ; side-push ( side-push pict n) ( if (<= n 0) empty-picture... ) ( corner-push pict n) ( if (<= n 1) empty-picture... ) 단, n = 0인 경우에는 empty-picture라고 가정하자. 추가로, 다음 fish-side-push와 fish-corner-push를 각각 frame1에서 display한 결 과를 보이시오 (capture할 것). fish-side-push ( side-push fish-tile 2) ) fish-corner-push ( corner-push fish-tile 2) ) 7
2.6 Problem 6: square-limit구현 및 테스트 아래의 정의에 따라 nonet을 이용하여 square-limit를 구현하시오.. 추가로, 다음 fish-square-limit를 display한 결과를 확인하시오 (capture할 것). fish-square-limit ( square-limit fish-tile 2) ) 참고로, display결과는 다음과 같아야 한다. 8
3 Triangle Fish조각대신에 Triangle조각을 사용하여 다음 그림이 나오도록 문제 2의 code 를 확장하시오. (triangle.rkt파일을 제출하시오. 실행후 다음 그림의 Display 결과가 나와야 함) 다시 말해, 아래 triangle-square-limit를 frame1에 display한 결과가 위 그림과 같이 되도록 문제 2의 코드를 확장하시오. triangle-square-limit ( square-limit triangle-tile 2) ) 9