… well, moreso I don’t know where to go with my code for now.
I’m currently taking an introduction to CG and have an assignment that involves a polygon corral (5 sided) in which a ball bounces. After much effort, I finally got it to work correctly and smoothly (figured out an error with how I used Double Buffering), but now I must manipulate my code so that it inclides 3 interior sphere (well, for my purposes, circles) obstacles upon which the ball must bounce upon. I understand the concept and believed that I had it implemented correctly, but the code does not work as intended, merely passes through the obstacles while continuing to correctly ricochet off the polygon’s inner walls.
Here is the main cpp code. It calls an external class Tigger that does the calculations for dot product, normal, unit normal, etc. as needed by the problem.
/*
Written and designed by Me
This is the OpenGL implementation of the
ball bounce program.
*/
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include "Tigger.h"
void display(void) {
float A[2] = { 2.0, 7.0};//point A on boundary of ball
float B[2] = {12.0, 1.0};//point B on boundary of ball
float C[2] = {23.0,11.0};//point C on boundary of ball
float D[2] = { 9.0,20.0};//point D on boundary of ball
float E[2] = { 1.0,20.0};//point E on boundary of ball
// Radii of Circle obstacles
float Radius[3]={ 2.0, 2.5, 2.5 };
// X Coordinates of Circle obstacles
float CenterX[3]={ 12.0, 15.0, 5.0 };
// Y Coordinates of Circle obstacles
float CenterY[3]={ 5.0, 12.5, 17.5 };
// Radius of Ball
float radius=0.125;
// Coordinates of center of ball
float center[2] = { 8.0, 11.0 };
// Velocity vector
float velocity[2] = { 6.0, 5.0 };
// Clear the entire display
glClear( GL_COLOR_BUFFER_BIT );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float T=0.001;
while ( T < 100 )
{
//Set initial time
//Setup distance array for Circle obstacle collision
float distance[3], x,y;
// Erase the ball by drawing the surface again
glColor3f( 20.0, 20.0, 20.0 );
glBegin(GL_POLYGON);
glVertex3f( 2.0, 7.0, 0.0);
glVertex3f(12.0, 1.0, 0.0);
glVertex3f(23.0,11.0, 0.0);
glVertex3f( 9.0,20.0, 0.0);
glVertex3f( 1.0,20.0, 0.0);
glEnd();
glFlush();
// Draw the ball (red)
glColor3f( 1.0, 0.0, 0.0 );
glPushMatrix();
glTranslatef(center[0], center[1], 0.0);
glutSolidSphere( radius, 25, 25);
glPopMatrix();
// Make sure the ball has been displayed
glFlush();
// Circle Obstacle 1
glColor3f( 0.0, 2.0, 0.0 );
glPushMatrix();
glTranslatef( CenterX[0], CenterY[0], 1.0 );
glutSolidSphere( Radius[0], 25, 25);
glPopMatrix();
glFlush();
// Circle Obstacle 2
glColor3f( 0.0, 2.0, 0.0 );
glPushMatrix();
glTranslatef( CenterX[1], CenterY[1], 2.0 );
glutSolidSphere( Radius[1], 25, 25);
glPopMatrix();
glFlush();
// Circle Obstacle 3
glColor3f( 0.0, 2.0, 0.0 );
glPushMatrix();
glTranslatef( CenterX[2], CenterY[2], 2.0 );
glutSolidSphere( Radius[2], 25, 25);
glPopMatrix();
glFlush();
// Slow the simulation down
//Sleep( 0.00003 );
// Set up Ball object through external class Tigger
// This does computations for new CENTER and VELOCITY
Tigger Ball(center,velocity);
// Find current distance from each Circle obstacle
for (int i=0; i<3; i++) {
x = (CenterX[i]-center[0]);
y = (CenterY[i]-center[1]);
distance[i] = sqrt( (x*x) + (y*y) );
}
//What happens when an obstacle impact occurs
if (distance[0]==Radius[0]){
Ball.normC(CenterX[0],CenterY[0]);
// Calculate Bounce Velocity
velocity[0]=Ball.newVx();
velocity[1]=Ball.newVy();
// Calculate Bounce center
center[0]=Ball.newCx();
center[1]=Ball.newCy();
}
else if (distance[1]==Radius[1]){
Ball.normC(CenterX[1],CenterY[1]);
// Calculate Bounce Velocity
velocity[0]=Ball.newVx();
velocity[1]=Ball.newVy();
// Calculate Bounce center
center[0]=Ball.newCx();
center[1]=Ball.newCy();
}
else if (distance[2]==Radius[2]){
Ball.normC(CenterX[2],CenterY[2]);
// Calculate Bounce Velocity
velocity[0]=Ball.newVx();
velocity[1]=Ball.newVy();
// Calculate Bounce center
center[0]=Ball.newCx();
center[1]=Ball.newCy();
}
// What happens when a perimeter impact occurs
else if (T==Ball.Time(A,B,C,D,E))
{
// Calculate Bounce Velocity
velocity[0]=Ball.newVx();
velocity[1]=Ball.newVy();
// Calculate Bounce center
center[0]=Ball.newCx();
center[1]=Ball.newCy();
T=0.001;
}
else
{
// Calculate the new center
center[0] += (velocity[0]*(T));
center[1] += (velocity[1]*(T));
}
glutSwapBuffers();
}
}
void
main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(600,600);
glutCreateWindow("Sphere In Irregular Pentagon");
glClearColor( 20.0, 0.0, 0.0, 0.0 );
glOrtho(0,25,0,25,-1,1);
glutDisplayFunc(display);
glutMainLoop();
}
If it helps, I’ll describe what I tried to do. My problem is set up that I start with a Ball of given center and velocity vector enclosed within the pentagon. What I did to get it to bounce is set up a while loop of infinity (while (1) ), in which the scene iterates by .001 seconds. I find the minimum time the ball will take to hit a surface (thus, the smallest non negatively timed surface collision) and have it reflect off that surface, else just increment the center by velocity times time ( C += V*T ).
For circle detection, established that for a collision to occur, the ball must be Radius distance from the center of the obstacle, and say that if at the given time in the loop that distance equals the radius of the obstacle, reflect, with the normal being the line from the center of the obstacle through the point of contact on the circumference. I am assuming that the way I impliment my code prevents me from being able to use the distance as a proof when the time is the variable, but if I prove according to Time, I would have 2 uknowns: Time and the position of the Hit, and I can’t seem to work with that right now.
Also, can someone help me use my code successfully using an glutIdleFunc() rather than the while loop?
Thanks alot in advance.