JRoop

10-20-2005, 10:55 PM

.. 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.

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.