Archived

This topic is now archived and is closed to further replies.

[Solved] Code for a rolling ball

This topic is 5142 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have trouble writing a code that displays a ball rolling. The ball roll(x and y axis) and pivot(z axis). I did this but it doesn't seem t work very well
/*--- Draw the ball ---*/
// angle is the angle of the rolling with the X axis

// rotationXY.norm() is the number of degrees the ball has to be rotated


texture.bind();						// Apply the texture to the sphere

	
glTranslated(position.x, position.y, position.z);	// Move the sphere to its position


glRotated(rotationZ.norm(), 0, 0, 1);			// Pivoting


glRotated(angle, 0, 0, -1);
glRotated(rotationXY.norm(), 1, 0, 0);			// Rolling

glRotated(angle, 0, 0, 1);

gluSphere(quadric,radius,sections*2,sections);		// Draw the sphere

Could someone help me with that ? Thanks. [edited by - Roming22 on November 9, 2003 6:44:21 PM] [edited by - Roming22 on November 12, 2003 6:04:21 PM]

Share this post


Link to post
Share on other sites
I''m not sure exactly what you are trying to accomplish by looking at your code. I guess what you want to do is have a ball roll. The ball may also pivot. I''m not sure if you''ve seen this, but here are a few points.
1. Make sure the order of your rotations is correct.
2. glPushMatrix() and glPopMatrix() are your friends.

So, if you wanted to roll the ball forward, you''d have 0 degrees of rotation on the pivot axis, and however many degrees of roll on the X axis.

glPushMatrix();
glRotated(pivot, 0, 0, 1);
glRotated(roll_amount, 1, 0, 0);
glPopMatrix();

This is simple to do if you are only rolling the ball in one direction, with an angle of rotation. Things get hairy once you place the ball on a nonuniform surface, with hills and bumps and such. When that happens, you''ll just have to figure out how much the ball is rolling, then you use the normal of your current plane and your speed of roll to figure out the ratio to use to figure out how much roll occurs on each axis.

Hopefully that answered a few questions. If I was wrong, just tell me!

"Donkey, if it were me, you''d be dead."
I cna ytpe 300 wrods pre mniute.

Share this post


Link to post
Share on other sites
Thanks for the reply!

1. That might be the problem, but I''m not sure
2. Is use them around the code I''ve posted. I''m concerned about the rotations.

For the hairy thing:
Hmm, it does not happens, but what happens is that my ball is sliding thus rolling another way that the one it''s actually moving.
The ball is not rolling only in the x direction so I can''t use

glRotated(roll_amount, 1, 0, 0);

I have to compose the rotation on the X and Y axis. That''s why the rolling is surrounded by the two rotation.

In fact I think the code is ok, and that my troubles might come from somewhere else.

Share this post


Link to post
Share on other sites
Nope I do have a problem in the code (and maybe elsewhere too).

My ball is simultaneously rotating around the three axis, and I can't display it. I know I can't do
glRotated(rotX,1,0,0);
glRotated(rotY,0,1,0);
glRotated(rotZ,0,0,1);


because it would mean "first rotate around the Z axis, then the Y axis and finally the X axis", so it's not simultaneous.

How can I apply them all at once?

Any help would be really appreciated.

Thanks.

[edited by - Roming22 on November 10, 2003 4:44:11 PM]

Share this post


Link to post
Share on other sites
Just to clear up an issue:
1. Do you want to perform the "rolling" part of the roll, not the pivot, in one rotation?

If your answer to question one was yes, you may have a slight problem. In order to perform the roll in one glRotated() command, you must know the absolute amount of roll to perform. This is very simple to find out: If you know how far you are going to roll, i.e. distance, you can find the amount of roll:
roll_in_degrees = (distance / circumference) * 360 degrees;
roll_in_radians = (distance / circumference) * pi/180;

Then ,you must know exactly how much roll is being performed on each axis, forward and sideways, X and Y, preferrably in a percentage. Then, you call
glRotated(roll_in_degrees, forward_roll_percent, sideways_roll_percent, 0);

That''s if your answer to question one was yes. If you are doing a simple forward with pivot, these are your calls:
glRotated(pivot, 0, 0, 1);
glRotated(roll_y, 0, 1, 0);
glRotated(roll_x, 1, 0, 0);

Also, I''m assuming that you are considering "up" to be along the Z axis, due to your previous posts. Just be sure to call your rotation commands in the right order. If you have the "Red Book", it''s in one of the first couple of chapters.

"Donkey, if it were me, you''d be dead."
I cna ytpe 300 wrods pre mniute.

Share this post


Link to post
Share on other sites
So, if I know how much rotation is applied to each axis all I have to do is

totalRot = xRot + yRot + zRot;
glRotate(totalRot, xRot/totalRot, yRot/totalRot, zRot/totalRot);

I''m going to try that! I had tried
glRotate(1, xRot, yRot, zRot);
unsuccesfully, but it makes sense that I can scale only from 0 to 1.

Share this post


Link to post
Share on other sites
Hmmm. My guess is that quaternions are the way to go to solve your problem.


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

Share this post


Link to post
Share on other sites
Quaternions may be the way to go, but they aren''t always easy to work with, as they aren''t easy to conceptualize. If he sticks with this method, he''ll understand how it works, and gain a deeper understanding of what his code is actually doing.

"Donkey, if it were me, you''d be dead."
I cna ytpe 300 wrods pre mniute.

Share this post


Link to post
Share on other sites
Well I tried:

glRotated(90.0, 0.5, 0, 0);

but it does a 90 angle. It''s not taking into account the 0.5 to decrease the rotation to 45 degrees... I''m stuck, I can''t get that ball to roll! I thought it would be easier. How wrong I was !!!

Share this post


Link to post
Share on other sites
I'd be willing to try with quaternions. Can someone give me the formula for the matrix.
I have a rotation of aX degrees around the x Axis, aY degrees around the y axis and aZ degrees around the z axis. How do I calculate de transformation matrix ? It is not just

aX 0 0 0
0 ay 0 0
0 0 aZ 0
0 0 0 1

is it?

Can I calculate it by adding the matrix of the rotation on each axis:

cos aY + cos aZ -sin aZ sin aY 0

sin aZ cos aX + cos aZ -sin aX 0

-sin aY sin aX cos aX + cos aY 0

0 0 0 1



[edited by - Roming22 on November 12, 2003 2:15:25 PM]

Share this post


Link to post
Share on other sites
I've found something that can be interesting. glRotated(angle, x, y, z) is performing the rotation angle around the vector (x,y,z). That's why glRotated(90, .5, 0, 0) did not rotate the ball at 45 degrees.

I guess I need to do some math to calculate the rotation that is the sum of the rotation on each axis. Then I would have the angle of the rotation and the vector of the rotation, and would just have to call glRotate accordingly.

So, is there any way to do that (I have a vector class with dot and cross product, calcul of an angle between 2 vectors).

[edited by - Roming22 on November 12, 2003 3:11:15 PM]

Share this post


Link to post
Share on other sites
I am talking to myself ?

I don''t care, I''ve found the solution.

First I needed a matrix in my class:

double rotationMatrix[16];

Then I needed to initialize it as the Identity (once, at the very beginning of the game):

glPushMatrix();
glLoadIdentity();
glGetDoubled(GL_MODELVIEW__MATRIX, rotationMatrix);
glPopMatrix();

Afterwards, each time the ball rotates of an angle alphe around the axis (x,y,z) I have to do the following:

glPushMatrix();
glLoadIdentity();
glRotated(alpha, x, y, z)
glMultMatrixd(rotationMatrix);
glGetDoubled(GL_MODELVIEW__MATRIX, rotationMatrix);
glPopMatrix();

Finally when drawing the ball I do:

glPushMatrix();
glTranslate(position.x, position.y, position.z);
glMultMatrixd(rotationMatrix);
gluSphere(quadric,radius,sections*2,sections);
glPopMatrix();

And that makes my ball(s) roll and pivot the way it should.
I could find it out thanks to the code of BilliardGL. It wasn''t easy to figure everything out as the code is in german, and I don''t speak a word of it, which made it difficult to find the right classes and functions (and for your information, a ball is a "kugel" in german).

Share this post


Link to post
Share on other sites
Yay !
There are a couple other solutions that are pretty similar :
- use your own matrix product function, so you don''t have to modify the OpenGL matrix stacks (this one is easy).
- use quaternions instead of matrices : a quaternion is used to hold a rotation ; you can use the quaternion product to compose rotations, and it''s quite easy to extract the axis and the angle of a quaternion. You''ll probably find a bunch of quaternion classes using a search engine.
Hmmm who said "if it''s not broken, don''t fix it" ?


SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

Share this post


Link to post
Share on other sites
Yep, I won''t touch it.

I guess the OpenGL calls are very fast and therefore I think that adding a quaternion class or doing my own matrix multiplication will result in a performance decrease.

But that''s my guess...

Share this post


Link to post
Share on other sites
Don't you have to use radians with glRotatef()?

*sorry I didn't see you were using glRotated() not that I know if it makes any difference. Does d stand for "degrees" as opposed to "double"?

[edited by - strider44 on November 13, 2003 8:13:39 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Roming22
I guess the OpenGL calls are very fast and therefore I think that adding a quaternion class or doing my own matrix multiplication will result in a performance decrease.



Not sure about that... Your hand-coded rotation functions could be inlined, so it might be a bit faster...
But I guess you don''t rotate your ball 1000 times per frame, so this is not relevant...



SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

Share this post


Link to post
Share on other sites