Skip to main content
gamedev.net
🔒 Locked

Rolling balls

Started by BSXrider 9 replies 1.5k views
Original Post
BSXrider
BSXrider
I''m trying to create the effect of balls rolling in my Pong game. I thought his would do it: glPushMatrix(); glTranslatef(xcoord,ycoord,zcoord); glRotatef( xcoord * 360.0f/(2 * PI * radius), 0, 1, 0); glRotatef(-ycoord * 360.0f/(2 * PI * radius), 1, 0, 0); glCallList(ballList); glPopMatrix(); If the ball rolls in just one "direction" i.e. purely up and down or purely left and right then the above code works. But if it''s rolling at an angle, say 45° between x and y then it does very bizarre things. Is this an example of gimbal lock, or am I just doing something stupid? - seb
johnb
johnb
You''re doing it wrong. You need to rotate it about a horizontal (i.e. in the x-y plane) axis which is perpendicular to the direction of motion. The direction of motion is given by the velocity, which also dictates how quickly it rotates.

So do something like

vDir = vCoord - vLastCoord [velocity in units per frame]
fRot = sqrt(vDir.x + vDir.x + vDir.y * vDir.y) [speed]
vAxis = {vDir.y, -vDir.x, 0} [ axis perpendicular to direction of travel

and use these to build your matrix like this

glRotatef(fRot * 360.0f/(2 * PI * radius), vAxis.x, vAxis.y, 0);

You may need to change a sign, e.g. of fRot in the glRotatef, but otherwise this should work.
John BlackburneProgrammer, The Pitbull Syndicate
BSXrider
BSXrider
I thought that might be it. Cheers then. Will give it a shot. It already looks great - that should make it look excellent!
BSXrider
BSXrider
No it's not that simple johnB.

Think about it. If the ball's moving in a constant direction and redrawing with that lot each time then the ball will rotate (from what it would look like as if stationary) but will always rotate by the same amount. I need to adapt your code so that it's cumulative, if you see what I mean.

- seb

Edited by - bsxrider on February 13, 2002 1:23:47 PM
BSXrider
BSXrider
This sort of works:

glPushMatrix();
glTranslatef(xcoord,ycoord,zcoord);
static float r=0;
float length = sqrt(vx*vx + vy*vy);
rot += length * seconds;

glRotatef(rot * 360.0f/(2 * PI * radius), -vy, vx, 0);

glCallList(ballList);

glPopMatrix();

Rolls nicely, but looks horrible when the ball changes direction.

- seb
BSXrider
BSXrider
thinking I''m going to have to keep the angles as members and update them every frame...
Blechx
Blechx
I have a similar quesition, although i dont need to calculate the angles, i already have them. i have 2 angles to rotate tthe ball in.

angle one around X-axis
angle two around Z-axis

note these are axises of the WORLD, not the ball.

im using opengl for gfx and am doing like this now.

glRotatef(m_xrot,1.0f,0.0f,0.0f);
glRotatef(-m_zrot,0.0f,0.0f,1.0f);

DrawBall();

this works only if one of the angles is 0.

thanks in advance and sorry if the answer has been given already.

[edited by - Blechx on November 16, 2003 2:30:05 PM]
YoshiN
YoshiN
I actually had to do this for a homework assignment.

What I did was store the direction as a vector (I made a class for that), and then I found the cross product of the UP vector and the vector representing the distance, this will give you the axis of rotation (think about it, the cross product will be perpendicular to both vectors). Then to find the distance to translate it, just remember that the displacement (ie: the arc of the sphere) is equal to r*angle in radians, or Pi*r*angle/180 in degrees. Find this value, and multiply it by the unit vector in the direction of the rolling. I can post some code if you need it.
-YoshiXGXCX ''99
Blechx
Blechx
the translation and angle calculating is already done, the only thing i need is the commands to rotate the ball with, (preferrably opengl syntax) And im no good at all with english math expressions :/ code would be appriciated
YoshiN
YoshiN
Okay, here some code from the program I wrote (I had to roll a ball from point A to B, B to C and then B to A), however it seems as if you are intending to do this a different way. If this doesn''t help you out let me know and I can code up something that will work with the parameters you have.


// initializing code

g_unit = g_AB.unitVector(); // set the unit vector in the direction of AB


g_sphereLoc = g_aLoc;

// reset the angle

g_angleSphere = 0.0f;

// change the rotational vector to VUP x AB

g_rot = g_VUP.cross(g_AB);

// ...


// updating code

// incriment the angle of rotation

g_angleSphere += 0.5f;

// update the direction vector

g_dir = g_unit*(PI180*g_angleSphere);

// ...


// drawing code

// translate the sphere

glPushMatrix();
glTranslatef(g_sphereLoc.x, g_sphereLoc.y, g_sphereLoc.z);
glTranslatef(g_dir.i, g_dir.j, g_dir.k);
glRotatef(g_angleSphere, g_rot.i, g_rot.j, g_rot.k);

// set the color to golden yellow for the sphere

glColor3f(1.0, 0.84, 0.0);

// draw the sphere

drawSphere();
glPopMatrix();


I have two classes, Vector3f and Vertex3f. g_AB, g_VUP, g_dir and g_rot are vectors whereas g_sphereLoc and g_aLoc are vertices. g_angleSphere is just a float representing the angle that the ball has rotated so far. PI180 is a constant set to Pi/180 (to convert degrees to radians).

In the initialization code you can see I am setting g_unit equal to the unit vector pointed in the same direction as the vector AB (which is the direction that the ball is rolling). I have set the initial location of the sphere to point A. The angle of rotation has been set to 0, and the axis of rotation is set to the cross product of the UP vector and the vector AB (you could also use the g_unit vector).

In the updating code, I have incrimented the angle by which to rotate the ball, and then calculated the magnitude of the displacement of the ball (which as I said before is equal to the radius*angle). Since the radius is one all I have to do find the angle in radians. After finding the magnitude I multiplied the unit vector by the magnitude so that the translate has both a direction and a distance.

In the drawing code I first rotated the ball by the angle specified around the axis I computed in the initialization. I then translated the ball the appropriate distance in the appropriate direction and also translated it to point A.
-YoshiXGXCX ''99
Blechx
Blechx
I dont think taht code applies to my problem really :/ (or im just to stupid to understand it)
you seem to be using one angle only, i use 2.

i basicly just need a way of rotating it according to those 2 angles, this distance calculation and translating i have no use for. The ball will only rotate vertical or horizontal, never diagonal, if this helps.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.