sicp-ex-2.49


 ;; Exercise 2.49 
 (let ((tl (make-vect 0 1)) 
       (tr (make-vect 1 1)) 
       (bl (make-vect 0 0)) 
       (br (make-vect 1 0))) 
   ;; a 
   (segments->painter (list 
                       (make-segment bl tl) 
                       (make-segment tl tr) 
                       (make-segment tr br) 
                       (make-segment br bl))) 
   ;; b 
   (segments->painter (list 
                       (make-segment bl tr) 
                       (make-segment br tl)))) 
    
 (let ((l (make-vect 0 0.5)) 
       (t (make-vect 0.5 1)) 
       (r (make-vect 1 0.5)) 
       (b (make-vect 0.5 0))) 
   ;; c 
   (segments->painter (list 
                       (make-segment l t) 
                       (make-segment t r) 
                       (make-segment r b) 
                       (make-segment b l)))) 

<< Previous exercise (2.48) | Index | Next exercise (2.50) >>


caesarjuly

I think my solution is more accurate

  
 (define (base frame) (origin frame)) 
 (define (right frame) (add-vector (base frame) (edge1 frame))) 
 (define (left frame) (add-vector (base frame) (edge2 frame))) 
 (define (top frame) (add-vector (right frame) (edge2 frame))) 
  
 (define (frame-painter frame)  
     (let ((b (make-segment (base frame) (right frame))) 
           (l (make-segment (base frame) (left-frame))) 
           (t (make-segment (left-frame) (top-frame))) 
           (r (make-segment (right-frame) (top-frame)))) 
         ((segments->painter (list b l t r)) frame))) 
  
 (define (x-painter frame)  
     (let ((h (make-segment (left frame) (right frame))) 
           (v (make-segment (base frame) (top-frame)))) 
         ((segments->painter (list h v)) frame))) 
  
 (define (middle-painter frame)  
     (let ((b (/ (add-vector (base frame) (right frame)) 2)) 
           (l (/ (add-vector (base frame) (left frame)) 2)) 
           (t (/ (add-vector (left frame) (top frame)) 2)) 
           (r (/ (add-vector (right frame) (top frame)) 2))) 
         ((segments->painter (list (make-segment b r)  
                                   (make-segment b l) 
                                   (make-segment l t) 
                                   (make-segment r t)))  
         frame))) 

mathieub

@caesarjuly Unless '/' is overloaded somehow and performs division on pairs, your solution will not work. Also, there's no need to pass the frame argument to your painters, segments->painter returns a lambda that will accept the frame as it's argument.


brave one

  
  
  
 ; sorry no make-<something> and selectors here, too much to type! 
  
 ; a. 
 (define outline 
   (let ((segments '( 
                     ((0 0) (0 1)) 
                     ((0 1) (1 1)) 
                     ((1 1) (1 0)) 
                     ((1 0) (0 0)) 
                    ))) 
     (segments->painter segments))) 
  
 ; b. 
 (define cross 
   (let ((segments '( 
                     ((0 0) (1 1)) 
                     ((0 1) (1 0)) 
                    ))) 
     (segments->painter segments))) 
  
 ; c. 
 (define diamond 
   (let ((segments '( 
                     ((0 0.5) (0.5 1)) 
                     ((0.5 1) (1 0.5)) 
                     ((1 0.5) (0.5 0)) 
                     ((0.5 0) (0 0.5)) 
                    ))) 
     (segments->painter segments))) 

SophiaG

The wording of the exercise seems to imply these functions should take a frame as input and calculate the segments based on that, which would also be much more useful should one intend to actually use them for drawing. Here's my answer given that:

(Also including coordinates for wave, aka George, pulled from a comment on Weiqun Zhang's blog by someone calling themselves "physjam")

 (define (outline->painter frame) 
   (let ((origin2 (make-vect  
                   (- (xcor-vect (edge2-frame frame))  
                      (xcor-vect (origin-frame frame))) 
                   (- (ycor-vect (edge1-frame frame))  
                      (ycor-vect (origin-frame frame)))))) 
     (segments->painter  
      (list           
       (make-segment (origin-frame frame) (edge1-frame frame)) 
       (make-segment (edge1-frame frame) origin2) 
       (make-segment origin2 (edge2-frame frame)) 
       (make-segment (edge2-frame frame) (origin-frame frame)))))) 
  
 (define (X->painter frame) 
   (let ((origin2 (make-vect  
                   (- (xcor-vect (edge2-frame frame))  
                      (xcor-vect (origin-frame frame))) 
                   (- (ycor-vect (edge1-frame frame))  
                      (ycor-vect (origin-frame frame)))))) 
     (segments->painter  
      (list           
       (make-segment (origin-frame frame) origin2) 
       (make-segment (edge1-frame frame) (edge2-frame frame)))))) 
  
 (define (diamond->painter frame) 
   (let ((midpoint1 (sub-vect (edge1-frame frame) (origin-frame frame)))  
         (midpoint2 (sub-vect origin2 (edge1-frame frame)))  
         (midpoint3 (sub-vect origin2 (edge2-frame frame))) 
         (midpoint4 (sub-vect (edge2-frame frame) (origin-frame frame)))) 
     (segments->painter  
      (list           
       (make-segment midpoint1 midpoint2) 
       (make-segment midpoint2 midpoint3) 
       (make-segment midpoint3 midpoint4) 
       (make-segment midpoint4 midpoint1))))) 
  
 (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)) 
                       ))) 
 ;George!