Chapter 2, Building Abstractions with Data
Section - 2.2 - Hierarchical Data and the Closure Property
Exercise 2.49
Note that in all the exercises, we can use coordinates of a unit square i.e. $0 \le x \le 1$ and $0 \le y \le 1$.
Now the method frame-coord-map
will maps our coordinates to the given frame.
(a)
As shown in the book, if we take $x = 0$ and $y = 0$, in the unit square it will be transformed to origin of the designated frame. Similarly it follows for any value of $x$ and $y$.
Thus, to draw the outline of the frame, we just need to draw outline of unit square. The method frame-coord-map
will take care to transform our points to
the points in the designated frame.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#lang sicp
(#%require sicp-pict)
(define draw-frame
(
(lambda ()
(let (
(v1 (make-vect 0 0))
(v2 (make-vect 0 0.99))
(v3 (make-vect 0.99 0.99))
(v4 (make-vect 0.99 0))
)
(let (
(sgm1 (make-segment v1 v2))
(sgm2 (make-segment v2 v3))
(sgm3 (make-segment v3 v4))
(sgm4 (make-segment v4 v1))
)
(segments->painter (list sgm1 sgm2 sgm3 sgm4))
)
)
)
)
)
Output/Test:
1
2
> (paint draw-frame)
; A unit square is drawn
Ideally (draw-frame (make-frame (make-vect 0 0) (make-vect 5 5) (make-vect 10 10)))
should also draw the outline of the passed frame. It apparently does not work.
It seems the draw-line
procedure is works correctly only while using paint
.
The problem with paint
is it draws only in a unit square frame. Thus to actually verify that points are correctly transformed and can outline any frame is possible
only if procedure segments-painter
are implemented without using draw-line
. Thus instead of draw-line
, use some new procedure which invokes Racket Graphics package
to draw line.
Currently because of time constraint, I am using segments-painter
currently available with sicp package of Dr Racket.
(b)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#lang sicp
(#%require sicp-pict)
(define draw-X
(
(lambda ()
(let (
(v1 (make-vect 0 0))
(v2 (make-vect 0 0.99))
(v3 (make-vect 0.99 0.99))
(v4 (make-vect 0.99 0))
)
(let (
(sgm1 (make-segment v1 v3))
(sgm2 (make-segment v2 v4))
)
(segments->painter (list sgm1 sgm2))
)
)
)
)
)
Output/Test:
1
2
> (paint draw-X)
; X is drawn
(c)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#lang sicp
(#%require sicp-pict)
(define draw-diamond
(
(lambda ()
(let (
(v1 (make-vect 0 0.5))
(v2 (make-vect 0.5 0.99))
(v3 (make-vect 0.99 0.5))
(v4 (make-vect 0.5 0))
)
(let (
(sgm1 (make-segment v1 v2))
(sgm2 (make-segment v2 v3))
(sgm3 (make-segment v3 v4))
(sgm4 (make-segment v4 v1))
)
(segments->painter (list sgm1 sgm2 sgm3 sgm4))
)
)
)
)
)
(d)
It is too time consuming and similar to earlier exercises. As it is used in next exercise, I am using a solution from wiki:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(define wave
(segments->painter
(list
(make-segment (make-vect .25 0) (make-vect .35 .5))
(make-segment (make-vect .35 .5) (make-vect .3 .6))
(make-segment (make-vect .3 .6) (make-vect .15 .4))
(make-segment (make-vect .15 .4) (make-vect 0 .65))
(make-segment (make-vect 0 .65) (make-vect 0 .85))
(make-segment (make-vect 0 .85) (make-vect .15 .6))
(make-segment (make-vect .15 .6) (make-vect .3 .65))
(make-segment (make-vect .3 .65) (make-vect .4 .65))
(make-segment (make-vect .4 .65) (make-vect .35 .85))
(make-segment (make-vect .35 .85) (make-vect .4 1))
(make-segment (make-vect .4 1) (make-vect .6 1))
(make-segment (make-vect .6 1) (make-vect .65 .85))
(make-segment (make-vect .65 .85) (make-vect .6 .65))
(make-segment (make-vect .6 .65) (make-vect .75 .65))
(make-segment (make-vect .75 .65) (make-vect 1 .35))
(make-segment (make-vect 1 .35) (make-vect 1 .15))
(make-segment (make-vect 1 .15) (make-vect .6 .45))
(make-segment (make-vect .6 .45) (make-vect .75 0))
(make-segment (make-vect .75 0) (make-vect .6 0))
(make-segment (make-vect .6 0) (make-vect .5 .3))
(make-segment (make-vect .5 .3) (make-vect .4 0))
(make-segment (make-vect .4 0) (make-vect .25 0))
)
)
)