DESIGN DOCUMENT: BOUNCING BALL BOX Jesse Tov SYNOPSYS ======== Red and blue balls, with initially random position and velocity, bounce inside a box. When a red ball collides with a blue ball, both balls disappear. The user may add new balls, with random position and velocity, by pressing b for blue and r for red. If a ball collides with more than one opposite-color ball at once, all balls involved in the collision are removed. PARAMETERS ========== - The width and height of the box - The radius of a ball - Range from which initial velocities are chosen - Numbers of initial balls INFORMATION ANALYSIS & DATA DEFINITIONS ======================================= At each point in time, there are a number of balls, each with a position and velocity. This is all the information needed in our world. Two possible representation of the ball world: 1) ;; A Velocity is (make-vel Number Number) (define-struct vel (dx dy)) ;; A Ball is (make-ball Posn Velocity) (define-struct ball (posn vel)) ;; A LoB is one of: ;; -- empty ;; -- (cons Ball LoB) ;; A BallWorld is (make-ball-world LoB LoB) ;; interp. one field contains red balls and the other blue (define-struct ball-world (reds blues)) 2) ;; A Velocity is (make-vel Number Number) (define-struct vel (dx dy)) ;; A Ball is (make-ball Posn Velocity Color) (define-struct ball (posn vel color)) ;; A LoB is one of: ;; -- empty ;; -- (cons Ball LoB) ;; A BallWorld is LoB Advantages of 1: - Possibly easier to find collisions. Advantages of 2: - Easier to extend with (many) more ball colors later. I intend to try 1, but if it gives me trouble, I might try 2. MAIN PROGRAM TASKS ================== - Generate random balls - Update ball positions over time - update x and y by dx and dy - Detect collisions between balls and walls - for ball collisions, detect if the distance between the centers is less than the sum of the radii - for wall collisions, detect if the distance from the ball center to the wall is less than the radius; what about corners? - Figure out which way a ball should bounce - ? - Respond to user input WISHLIST ======== render-ball-world : BallWorld -> Scene To render the ball world handle-keyboard : BallWorld KeyEvt -> BallWorld To add random balls to the world at user request handle-tick : BallWorld -> BallWorld To update to the next frame of the animation update-positions : BallWorld -> BallWorld To move each ball by its velocity remove-collisions : BallWorld -> BallWorld To remove balls that have collided from the ball world remove-collisions-many : LoB LoB -> LoB To remove all the balls in the first list that collide with a ball in the second list remove-collisions-one : LoB Ball -> LoB To remove all balls from the list that collide with the given ball collides? : Ball Ball -> Boolean Do the two balls collide? reflect-ball : Ball -> Ball Compute the bounce for one ball, if necessary OPEN QUESTIONS & ANTICIPATED DIFFICULTIES ========================================= - What helper functions will reflect-ball require? - In what order should we move balls and check for collisions? - What should happen when all the balls run out? - I really don't know how to do reflection yet. IMPLEMENTATION PLAN =================== 1. Rendering first, because it might make it easier to understand the rest incrementally. 2. Write some of the low level helpers, such as collide?, and test them. (If I turn out not to need them as I anticipate, this could be a waste of time.) 3. Figure out reflection. 4. Put together the high level tick handler. 5. Handle user interaction.