This page was last updated: October 11, 2022
The scenario is that a ball is bouncing around in a box. You are to create one new function, called Bounce(dt), to advance its motion one time step, check for a collision with the walls or the floor, and then correctly handle the bounces.
Here is a skeleton of the required Bounce(dt) function:
// the ball radius: const float RADIUS = { 0.50f }; // where the walls are: const float XLEFT = { -5.f }; const float XRIGHT = { 5.f }; const float YBOTTOM = { -3.f }; // flags to indicate which surface was hit: // (these are #define'd so that they can be used in a switch statement) #define NOTHING_HIT (-1) #define HIT_LEFT 0 #define HIT_RIGHT 1 #define HIT_FLOOR1 2 #define HIT_FLOOR2 3 // a tolerance to allow for floating-point roundoff problems: const float EPSILON = { 0.001f }; // ********** FROM THE START TO HERE WILL BE PROVIDED IN THE GRADING SCRIPT ********** // ********** ONLY TURN IN FROM HERE DOWN, Bounce( ) PLUS WhoAmI() ********** void Bounce( float dt ) { while( dt > EPSILON ) { float tmin = dt; // minimum time to do something int which = NOTHING_HIT; // which reason was it for doing the something // these four collision times are computed using your projectile motion equations: float tleft = ????; // time to hit the left wall if( tleft > EPSILON && tleft < tmin ) { tmin = tleft; which = ?????; } float tright = ????; // time to hit the right wall if( tright > EPSILON && tright < tmin ) { ????? } // the y collision with the floor involves a quadratic equation // thus, there are 2 times to collision, tfloor1 and tfloor2: float tfloor1 = ????; // time to hit the floor if( tfloor1 > EPSILON && tfloor1 < tmin ) { ????? } float tfloor2 = ????; // time to hit the floor (note there are 2 answers) if( tfloor2 > EPSILON && tfloor2 < tmin ) { ????? } // 'tmin' is now set to the smallest of: // dt, tleft, tright, tfloor1, tfloor2 // 'which' is set to: // NOTHING_HIT, HIT_LEFT, HIT_RIGHT, HIT_FLOOR1, or HIT_FLOOR2 // to show what was the first thing hit // take a time step of time length tmin, using the projectile motion equations: // if a bounce is going to occur, tmin takes the ball right up next to the surface: // BE SURE TO USE tmin HERE, NOT dt: Xnow = Xnow + Vxnow*tmin; Vxnow = Vxnow; Ynow = Ynow + Vynow*tmin + 0.5*Gravity*tmin*tmin; Vynow = Vynow + Gravity*tmin; // a "bounce trick": if( Ynow < YBOTTOM+RADIUS ) Ynow = YBOTTOM+RADIUS; // floating point roundoff sometimes messes up if( Xnow < XLEFT+RADIUS ) Xnow = XLEFT+RADIUS; if( Xnow > XRIGHT-RADIUS ) Xnow = XRIGHT-RADIUS; // depending on what caused the bounce, change the proper velocity component: // if nothing was hit in this time step, just return: switch( which ) { case NOTHING_HIT: return; case HIT_LEFT: ?????; break; case HIT_RIGHT: ????? break; case HIT_FLOOR1: ????? break; case HIT_FLOOR2: ????? break; } dt -= tmin; // after the bounce, we might still have some time step left } }The Bounce( ) function takes as its input the time step you are trying to take. Its strategy is to see if it will hit a surface in that time step. If not, take the full dt step. If it will hit a surface, take just enough of a step to get right next to the surface. Then bounce by reversing the proper velocity component multiplied by the negative Coefficient of Restitution, and advance through what's left of the time step.
The ball has a radius called RADIUS. Take it into account just like the equations in the Collision notes do.
Turn in just the file bounce.cpp -- it should include only your Bounce( ) and WhoAmI( ) functions. Don't turn in all of those #defines. Don't turn in any .h files. Remove all your print statements.
To avoid a ton of arguments to Bounce( ), assume that these are global variables that you automatically get access to:
Xnow,Ynow | Current ball position |
Vxnow,Vynow | Current ball velocity |
Gravity | The acceleration due to gravity ("normal" gravity is negative) |
CoefRest | Coefficient of Restitution |
If you want to visually see if your program is working, here is the file BounceWrapper2019.zip for Visual Studio 2019. This is a graphics wrapper program and all the Visual Studio stuff that goes with it. Just unzip all of this into a separate folder and double click on the .sln file.
Warning -- the Bounce( ) function in this .zip file is crippled. You need to fill the details in.
Do not turn in the entire graphics program! Just turn in your Bounce( ) and WhoAmI( ) functions in a single .cpp file.
I will give you a .o file to test with. It will be similar to the grading program I will use. But, it will only tell you your final score. If you don't get full credit, it will not tell you what you are getting wrong. It is meant to reassure, not to replace your own testing!
Click here to get the test04.o file to test with. It is just like the grading program I will use, but it will only tell you your final score. If you don't get full credit, it will not tell you what you are getting wrong. It is meant to reassure, not to replace your own testing and debugging!
Use it like this (assuming the file you are planning to turn in is called proj04.cpp):
g++ proj04.cpp test04.o -o proj04
./proj04
Because you are compiling separately from my code, you will need the following lines up at the top:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <string>
#define _USE_MATH_DEFINES
#include <math.h>
const float RADIUS = { 0.50f };
const float XLEFT = { -5.f };
const float XRIGHT = { 5.f };
const float YBOTTOM = { -3.f };
// flags to indicate which surface was hit:
// (these are #define'd so that they can be used in a switch statement)
#define NOTHING_HIT -1
#define HIT_LEFT 0
#define HIT_RIGHT 1
#define HIT_FLOOR1 2
#define HIT_FLOOR2 3
// a tolerance to allow for floating-point roundoff problems:
const float EPSILON = { 0.001f };
const float TOL = { 0.1f };
extern float CoefRest;
extern float Gravity;
extern float Vxnow, Vynow;
extern float Xnow, Ynow;
You will not need these lines in your final turnin .cpp file.
Note that when you run your own tests, you will need a main( ) program.
You must not have a main( ) program
when you run with test04.o or when you turn in your .cpp file.
In those two cases, I am providing the main( ) program.
For those of you using your own Linux system and getting "PIE" error messages, try this version of the .o file:
Click here to get the test04B.o file to test with.
Your electronic turnin will be done at
http://engr.oregonstate.edu/teach
and will consist of:
This is due at 23:59:59 on the listed due date.
This project will be auto-graded by a script that will append your function to a main program, compile the combination, run the executable, and see if your functions produce the right numbers. The script that compiles your functions will use exactly the g++ seen before. If your function do not compile and link, your grade on this project will be a zero.
For grading, I will append your function to my test program and see if you get the right answers.
If your code does not compile, then your grade for this project is a zero!
Feature | Points |
---|---|
Right wall | 25 |
Left wall | 25 |
Floor | 25 |
Double bounce | 25 |
TOTAL | 100 |