CS 491 -- Fall Quarter 2022

Project #4: Collisions and Bouncing

Due: October 31

100 Points


This page was last updated: October 11, 2022


Requirements

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.

Global Variables You Will Need to Access

To avoid a ton of arguments to Bounce( ), assume that these are global variables that you automatically get access to:

Xnow,YnowCurrent ball position
Vxnow,VynowCurrent ball velocity
GravityThe acceleration due to gravity ("normal" gravity is negative)
CoefRestCoefficient of Restitution

Testing and Debugging

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.

Testing and Debugging

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!

How to Reassure Yourself That You Will Get Full Credit

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.

Turn-In

Your electronic turnin will be done at http://engr.oregonstate.edu/teach and will consist of:

  1. Your source file (bounce.cpp)

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.

Grading

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!

FeaturePoints
Right wall25
Left wall25
Floor25
Double bounce25
TOTAL100