;; The first three lines of this file were inserted by DrScheme. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-advanced-reader.ss" "lang")((modname hw02-reflect-v-too) (read-case-sensitive #t) (teachpacks ((lib "world.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "world.ss" "teachpack" "htdp"))))) ;;;------------------------------------------------------------------- ;; Note that list-ref is built-in to Scheme; Java calls it List.get(int). ;; let* is a form for introducing local constants. ;; ;; The following methods are specific to the image library (nonstandard) ;; image-width image-height pinhole-x pinhole-y ;; image->color-list color-list->image ;; The last functions convert between an image an one big long list of pixels. ; reflect-v : (-> image image) ; Reflect an image vertically (that is, make a mirror image). ; (define (reflect-v img) (let* {[w (image-width img)] [h (image-height img)] [new-pinhole-x (- (image-width img) (pinhole-x img) 1)] } (color-list->image (reflect-list-2d-v (image->color-list img) w h) w h new-pinhole-x (pinhole-y img)))) (check-expect (reflect-v (circle 20 'solid 'blue)) (circle 20 'solid 'blue)) (check-expect (reflect-v (rectangle 20 30 'outline 'green)) (rectangle 20 30 'outline 'green)) ; list-ref-2d : (-> (list-of any) int int int int) ; index into a list, as if it were a w-by-h 2-D array. ; (define (list-ref-2d lst w h i j) (list-ref lst (+ (* i w) j))) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 0 0) 'a) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 0 1) 'b) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 0 2) 'c) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 1 0) 'd) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 1 1) 'e) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 3 2 1 2) 'f) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 1 6 5 0) 'f) (check-expect (list-ref-2d (list 'a 'b 'c 'd 'e 'f) 6 1 0 5) 'f) ; reflect-list-2d-v : (-> lst int int) ; Given a list which *represents* a 2-d w-by-h array, ; return that 2-d array with each row reflected vertically ; (mirror-imaged). ; (define (reflect-list-2d-v data w h) (build-list (* w h) (lambda (i) (let* {[row (quotient i w)] [column (remainder i w)] } (list-ref-2d data w h row (- w column 1)))))) (check-expect (reflect-list-2d-v empty 0 0) empty) (check-expect (reflect-list-2d-v (list 'a 'b) 2 1) (list 'b 'a)) (check-expect (reflect-list-2d-v (list 'a 'b) 1 2) (list 'a 'b)) (check-expect (reflect-list-2d-v (list 'a 'b 'c 'd 'e 'f) 2 3) (list 'b 'a 'd 'c 'f 'e)) (check-expect (reflect-list-2d-v (list 'a 'b 'c 'd 'e 'f) 3 2) (list 'c 'b 'a 'f 'e 'd)) ;; This implementation is short, but rather inefficient -- processing ;; images as linked-list-of-pixel (rather than using arrays). ;; If (and ONLY if) this method is a bottleneck, ;; you can create methods list->array-2d and array-2d->list if you like. ;; Alternately, see standard a array library, "srfi/25". ;; ;; For the future fire-fighting assignment, it's much easier ;; to reflect the plane's image just once and cache the result; ;; that way, reflect-v is only called once, and its performance is moot.