Exercise 166: Modify connect-dots
Modify connect-dots so that it consumes an additional Posn structure to which the last Posn is connected.
Then modify render-poly to use this new version of connect-dots. Note: this new version is called an accumulator version.
This is perhaps not the ideal way to solve this question but I believe it is doing what has been asked.
It seems a little odd as it is defined as an "accumulator" version which normally means the answer
'accumulates' (or changes) as you recurse up or down the stack. In this case our accumulator remains unchanged and is used simply as a means to draw the link back to the original posn.
When we reach the end of the list of posns instead of returning an empty scene element to draw the rest of the polygon onto, I am returning an image with this last link already drawn in. The rest of the function is exactly the same, with the exception that we are passing our final-posn all the way down the stack.
; NELoP -> Image
; connect the Posns in p
(define (connect-dots p final-posn)
(cond
[(empty? (rest p)) (render-line MT final-posn (first p) )]
[else
(render-line
(connect-dots (rest p) final-posn) (first p) (second p) )]))
We need to change the way we call connect-dots to take into account our new function signature. instead of wrapping an additional render-line around the call to connect-dots, we pass back in the first posn in the list so that connect-dots knows where to attach the last posn back to.
; Polygon -> Image
; add the Polygon p into an image in MT
(define (render-polygon p)
(connect-dots p (first p)))
; check our rendering of a list of triangle is sane
(check-expect
(render-polygon
(list (make-posn 20 0) (make-posn 10 10) (make-posn 30 10)))
(add-line
(add-line
(add-line MT 20 0 10 10 "red")
10 10 30 10 "red")
30 10 20 0 "red"))
; check our rendering of a square is sane
(check-expect
(render-polygon
(list (make-posn 10 10) (make-posn 20 10)
(make-posn 20 20) (make-posn 10 20)))
(add-line
(add-line
(add-line
(add-line MT 10 10 20 10 "red")
20 10 20 20 "red")
20 20 10 20 "red")
10 20 10 10 "red"))
The following supporting code is copied directly from the book.
(require 2htdp/image)
; A Polygon is one of:
; – (list Posn Posn Posn)
; – (cons Posn Polygon)
(define MT (empty-scene 50 50))
; A NELoP is one of:
; – (cons Posn empty)
; – (cons Posn NELoP)
; Image Posn Posn -> Image
; draw a red line from Posn p to Posn q into im
(define (render-line im p q )
(add-line
im (posn-x p) (posn-y p) (posn-x q) (posn-y q) "red"))
; NELoP -> Posn
; extract the last Posn from p
(define (last p)
(cond
[(empty? (rest (rest (rest p)))) (third p)]
[else (last (rest p))]))
No comments:
Post a Comment