(unit/sig (;; random number generators for fp and integer intervals random-fp-interval ; fp fp -> fp random-int-interval ; int int -> int ;; ;; global constants LENGTH HEIGHT ; length and height of box MAX_SPEED ; the maximum speed of a particle G ; the gravitational constant ;; ;; slowing down/speeding up the show set-sleep-time! ; num -> void ;; ;; the particle representation (struct particle (x y speed-x speed-y)) ;; ;; visualize the movements go ; num world (world -> void) -> void ; where world = (listof (make-particle int int int int)) ) (import plt:userspace^) ;; ------------------ library functions -------------- (define random-fp-interval (lambda (low up) (+ low (/ (random (inexact->exact (round (- (* 100 up) (* 100 low))))) 100.)))) (define random-int-interval (lambda (low up) (+ low (random (- up low))))) ;; -------------- particles -------------------------- ;; Assumes: (define-struct particle (x y speed-x speed-y )) ;; delay to slow down action so graphics will be visible (define SLEEP_TIME 20000) (define set-sleep-time! (lambda (x) (if (and (number? x) (>= x 0)) (set! SLEEP_TIME x) (error 'set-sleep-time! "expects type as 1st arg; given ~s" x)))) (define sleep-for (lambda (ticks) (if (zero? ticks) 0 (add1 (sleep-for (sub1 ticks)))))) (define particle-position (lambda (p) (make-posn (particle-x p) (particle-y p)))) (define display-particle (lambda (p) (printf "The particle is at <~s,~s>.~n" (particle-x p) (particle-y p)) (printf "It moves at a speed of <~s,~s>.~n" (particle-speed-x p) (particle-speed-x p)) )) (define LENGTH 600) ; width and height of display, maximal coordinates (define HEIGHT 300) (define G -1.) (define MAX_SPEED 50) (define go (lambda (No_moves world0 move-all) ; displays a simulation of the list of particles named world ; inputs: ; No_moves: number of time steps in simulation ; output: ; none (dynamic-wind ; executes that commands open-graphics, (lambda () ...), close-graphics ; in sequence ; if (lambda () ...) generate a run-time error, dynamic wind ``catches'' ; the error and executes close-graphics. ; see documenation for dynamic wind in Dybvig's book ; open-graphics (lambda () (let* ([window (open-viewport "Bouncy" LENGTH HEIGHT)] [draw-pt (draw-pixel window)] [clear-pt (clear-pixel window)] [xtrans (lambda (x) (inexact->exact (round x)))] [ytrans (lambda (y) (inexact->exact (round (- HEIGHT y))))] [plot-sq (lambda (xint yint op) (op (make-posn (add1 xint) (add1 yint))) (op (make-posn (add1 xint) yint)) (op (make-posn (sub1 xint) (sub1 yint))) (op (make-posn (sub1 xint) yint)) (op (make-posn (add1 xint) (sub1 yint))) (op (make-posn xint (sub1 yint))) (op (make-posn (sub1 xint) (add1 yint))) (op (make-posn xint (add1 yint))))] [draw-dot (lambda (xint yint) (draw-pt (make-posn xint yint)) (plot-sq xint yint draw-pt))] [clear-dot (lambda (xint yint) (plot-sq xint yint clear-pt))]) (recur L ([No_moves No_moves][world world0]) (if (zero? No_moves) (void) (L (sub1 No_moves) (begin (for-each (lambda (xN yN) (clear-dot (xtrans xN) (ytrans yN))) (map particle-x world) (map particle-y world)) (move-all world) (for-each (lambda (xN+1 yN+1) (draw-dot (xtrans xN+1) (ytrans yN+1))) (map particle-x world) (map particle-y world)) (sleep-for SLEEP_TIME) world)))))) close-graphics))) )