2 (:use [sicp.ex2_23 :only (for-each)]
3 [pictlang.core :only (draw-line)]))
5 (declare flip-vert up-split flip-horiz transform-painter rotate90 rotate270)
16 (defn add-vect [v1 v2]
17 (make-vect (+ (xcor-vect v1)
22 (defn sub-vect [v1 v2]
23 (make-vect (- (xcor-vect v1)
28 (defn scale-vect [v s]
29 (make-vect (* s (xcor-vect v))
32 (defn make-frame [origin edge1 edge2]
33 (list origin edge1 edge2))
35 (defn origin-frame [frame]
38 (defn edge1-frame [frame]
41 (defn edge2-frame [frame]
42 (first (rest (rest frame))))
44 ;; we define a segment as a list of 2 vectors
45 (defn make-segment [v1 v2]
48 (defn start-segment [segment]
51 (defn end-segment [segment]
55 (defn beside [painter1 painter2]
56 (let [split-point (make-vect 0.5 0)
57 paint-left (transform-painter painter1
61 paint-right (transform-painter painter2
67 (paint-right frame))))
69 (defn below [painter1 painter2]
70 (rotate90 (beside (rotate270 painter1) (rotate270 painter2))))
72 (defn flipped-pairs [painter]
73 (let [painter2 (beside painter (flip-vert painter))]
74 (below painter2 painter2)))
76 (defn right-split [painter n]
79 (let [smaller (right-split painter (- n 1))]
80 (beside painter (below smaller smaller)))))
82 (defn corner-split [painter n]
85 (let [up (up-split painter (- n 1))
86 right (right-split painter (- n 1))
87 top-left (beside up up)
88 bottom-right (below right right)
89 corner (corner-split painter (- n 1))]
90 (beside (below painter top-left)
91 (below bottom-right corner)))))
93 (defn square-limit [painter n]
94 (let [quarter (corner-split painter n)
95 half (beside (flip-horiz quarter) quarter)]
96 (below (flip-vert half) half)))
98 (defn frame-coord-map [frame]
102 (add-vect (scale-vect (edge1-frame frame) (xcor-vect v))
103 (scale-vect (edge2-frame frame) (ycor-vect v))))))
105 (defn segments->painter [segment-list]
110 ((frame-coord-map frame) (start-segment segment))
111 ((frame-coord-map frame) (end-segment segment))))
116 (defn transform-painter [painter origin corner1 corner2]
118 (let [m (frame-coord-map frame)
119 new-origin (m origin)]
120 (painter (make-frame new-origin
121 (sub-vect (m corner1) new-origin)
122 (sub-vect (m corner2) new-origin))))))
124 (defn flip-vert [painter]
125 (transform-painter painter
130 (defn shrink-to-upper-right [painter]
131 (transform-painter painter
136 (defn rotate90 [painter]
137 (transform-painter painter
142 (defn squash-inwards [painter]
143 (transform-painter painter
145 (make-vect 0.65 0.35)
146 (make-vect 0.35 0.65)))
149 (defn up-split [painter n]
152 (let [smaller (up-split painter (- n 1))]
153 (below painter (beside smaller smaller)))))
156 (letfn [(split-fn [painter n]
159 (let [smaller (split-fn painter (- n 1))]
160 (f1 painter (f2 smaller smaller)))))]
163 (def right-split (split beside below))
164 (def up-split (split below beside))
166 (defn flip-horiz [painter]
167 (transform-painter painter
172 (defn rotate180 [painter]
173 ((repeatedly 2 rotate90) painter))
175 (defn rotate270 [painter]
176 ((repeatedly 3 rotate90) painter))