;; Teachpack: draw.ss (define-struct ball (radius x y x-dot y-dot color)) ;; A Ball is (make-ball Number Number Number Number Number Symbol) #| Template 1. Trivial case: Ball is entirely out of bounds. In that case, simply return true. 2. Divide: Draw the ball, erase it, then replace it by a moved copy. 3 Conquer: Nothing to do here. |# ;; move-ball-until-gone : Ball -> true ;; display a ball moving until it disappears from the window ;; uses generative recursion (define (move-ball-until-gone b) (cond [(out-of-bounds? b) true] [else (and (draw-and-clear-ball b) (move-ball-until-gone (move-ball b)))])) (define DELTA-T 1) ; controls speed of simulation (define DELAY 0.1) ; seconds between updates ;; move-ball : Ball -> Ball ;; models the movement of a ball (define (move-ball b) (make-ball (ball-radius b) (+ (ball-x b) (* DELTA-T (ball-x-dot b))) (+ (ball-y b) (* DELTA-T (ball-y-dot b))) (ball-x-dot b) (ball-y-dot b) (ball-color b))) ;; drawing window dimensions (define WIDTH 300) (define HEIGHT 300) ;; draw-and-clear-ball : Ball -> true ;; draws ball, waits a short time, then clears it (define (draw-and-clear-ball b) (and (draw-solid-disk (make-posn (ball-x b) (ball-y b)) (ball-radius b) (ball-color b)) (sleep-for-a-while DELAY) (clear-solid-disk (make-posn (ball-x b) (ball-y b)) (ball-radius b) (ball-color b)))) ;; out-of-bounds? : Ball -> Boolean ;; determines if the ball is completely outside the drawing window (define (out-of-bounds? b) {local [(define ball-left (- (ball-x b) (ball-radius b))) (define ball-right (+ (ball-x b) (ball-radius b))) (define ball-top (- (ball-y b) (ball-radius b))) (define ball-bottom (+ (ball-y b) (ball-radius b)))] (or (< ball-right 0) (> ball-left WIDTH) (< ball-bottom 0) (> ball-top HEIGHT))}) ;; test the program (start WIDTH HEIGHT) (move-ball-until-gone (make-ball 10 200 20 -3 4 'red))