Exercise 165: Here are two more ideas for defining render-poly
Use both ideas to define render-poly; make sure both definitions pass the test cases.
- render-poly could cons the last item of p onto p and then call connect-dots.
- render-poly could add the first item of p to the end of p via a version of add-at-end that works on Polygons.
1) This solution here seems a very natural way to do this. In my view it makes it more clear that you are completing the loop in order to make the polygon complete.
; Polygon -> Image
; add the Polygon p into an image in MT
(define (render-polygon1 p)
(connect-dots (cons (last p) p)))
2) This also seems fairly natural. The only downside to this method is the (trivial) requirement for the definition of the add-to-end method. Contrary to what the question may indicate, the version of add-to-end given works perfectly for posns already.
; Polygon -> Image
; add the Polygon p into an image in MT
(define (render-polygon2 p)
(connect-dots (add-at-end p (first p) )))
The add-to-end function below is taken directly from earlier in the chapter. The only change I have made is to the variable names to better indicate what they are doing in this context. This has no bearing on how the function works and I was almost hesitant to even change them. Years of having to enforce descriptive variable names on colleagues at work forced my hand though. I may need to break this habit if I'm going to write scheme like a native schemer!
; LoP Posn -> Posn
; Concatenates a Posn on to the end of a List Of Posns
(define (add-at-end list posn)
(cond
[(empty? list) (cons posn empty)]
[else (cons (first list) (add-at-end (rest list) posn))]))
; test we can draw a triangle
(check-expect
(render-polygon2
(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"))
; test we can draw a square
(check-expect
(render-polygon2
(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"))
Everything below here is taken direct from the example answer.
(require 2htdp/image)
; A Polygon is one of:
; – (list Posn Posn Posn)
; – (cons Posn Polygon)
(define MT (empty-scene 50 50))
; Polygon -> Image
; add the Polygon p into an image in MT
(define (render-polygon p)
(render-line (connect-dots p) (first p) (last p)))
; A NELoP is one of:
; – (cons Posn empty)
; – (cons Posn NELoP)
; NELoP -> Image
; connect the Posns in p
(define (connect-dots p)
(cond
[(empty? (rest p)) MT]
[else
(render-line
(connect-dots (rest p)) (first p) (second p))]))
; 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