# Rotational axis? for movement of ball

## Recommended Posts

MARS_999    1627
I have a ball on a track and right now the ball moves side to side and I change the rotation based on which key the user has pressed. Problem is when the user presses fwd and left/right the ball doesn't say 45 degrees. So to make the ball look a bit more realistic in movements what am I needing to do to get this ball to rotate correctly when moving 2 directions at once vs. 1(fwd,right, left) Their isn't any backwards...
//used to calculate playerDir and is a scalar
//used later on with a playerTransformMatrix to determine playerPos.xyz
velocityClamped = velocity;
NX::MATH::Clamp<float>(velocityClamped, .5f, 1.0f);

if(playerRight)
playerDir += velocityClamped * PLAYERDIR_ACCEL_CONSTANT * DIR_CHANGE_RATE;
if(playerLeft)
playerDir -= velocityClamped * PLAYERDIR_ACCEL_CONSTANT * DIR_CHANGE_RATE;

//for the rotation of the ball
if(playerRight)
rotMatrix.Rotate(angle * velocity, false, false, true);//z axis
else if(playerLeft)
rotMatrix.Rotate(-angle * velocity, false, false, true);//z axis
else
rotMatrix.Rotate(angle * velocity, true, false, false);//x axis


rotMatrix is a 4x4 matrix thanks

##### Share on other sites
Ariste    296
There's not much to go off of from that code, but if I understand correctly, you're trying to have the combination key-press LEFT + UP create a 45 degree rotation as opposed to a full 90 (or 0) degree rotation. The problem with your code, then, is the if/else if/else sequence. In the event of a LEFT + UP combination, only one of those if blocks is going to be executed; namely, the first one that evaluates to true.

Try changing the code to a series of simple ifs. This way, each of the statements that evaluates to true will be executed, not just the first one.

##### Share on other sites
MARS_999    1627
Nah that doesn't work, the ball goes all nuts like you are stretching it out and contracting it...

##### Share on other sites
Ariste    296
LOL. So much for listening to me [smile]

Out of curiosity, what does your code look like now?

##### Share on other sites
MARS_999    1627
I used this

if(playerRight)
rotMatrix.Rotate(angle * velocityClamped * .1f, false, false, true);
if(playerLeft)
rotMatrix.Rotate(-angle * velocityClamped * .1f, false, false, true);
if(playerFwd)
rotMatrix.Rotate(angle * velocity * .00025f, true, false, false);

##### Share on other sites
jyk    2094
Can you post your Rotate() function?

##### Share on other sites
MARS_999    1627
Hi jky,

I changed my Rotate to sepearate functions but still does the same thing as before. I can only rotate one axis at a time with this rotate function.

What I am wondering is do I need to do some kind of rotational velocity or angular velocity? I have no idea I am not looking for realistic simulation here, but would like the ball to spin on the correct axis when the player moves in those directions?

Thanks

//Rotate a 3D point in Radians not Degrees	void RotateX(T angle)	{	    T sine   = sin(angle);		T cosine = cos(angle);		matrix[5]  = cosine;		matrix[6]  = sine;		matrix[9]  = -sine;		matrix[10] = cosine;	}	//Rotate a 3D point in Radians not Degrees	void RotateY(T angle)	{	    T sine   = sin(angle);		T cosine = cos(angle);        matrix[0]  = cosine;		matrix[2]  = -sine;		matrix[8]  = sine;		matrix[10] = cosine;	}	//Rotate a 3D point in Radians not Degrees	void RotateZ(T angle)	{	    T sine   = sin(angle);		T cosine = cos(angle);        matrix[0] = cosine;		matrix[1] = sine;		matrix[4] = -sine;		matrix[5] = cosine;	}

##### Share on other sites
jyk    2094
What are the types of velocity and playerDir?

I notice that your rotation functions don't set the matrix to identity before setting the relevant elements. Is this intentional? This means that the results may be incorrect if the matrix is not already identity.

##### Share on other sites
MARS_999    1627
both are scalar floats and I call identity before the rotate in a separate call

##### Share on other sites
KOzymandias    132
Don't you need 3 rotation matrices, one for each axis, then rotMatrix would be the product of those 3 matrices (in the right order) ?
Your RotateX/Y/Z functions assume the matrix is identity, so you can't call those functions successively on the same matrix. It overrides part of the last rotation, stretching the ball.

##### Share on other sites
jyk    2094
Does velocity represent angular velocity? What does playerDir represent? Is it an angle? Also, where does the angle variable come from? (The lack of context makes it a bit difficult to make sense of the code, IMO.)

As for the 'rotate' functions, they should really set every element of the matrix to the appropriate value, rather than making assumptions about the previous state of the matrix (IMO). Also, I don't see you setting the matrix to identity anywhere in your code - are you sure it's set to identity before the rotation functions are called? Are you setting the matrix to identity and then making multiple calls to the rotation functions with the expectation that the rotations will accumulate in some way?

##### Share on other sites
MARS_999    1627
Quote:
 Original post by jykDoes velocity represent angular velocity? What does playerDir represent? Is it an angle? Also, where does the angle variable come from? (The lack of context makes it a bit difficult to make sense of the code, IMO.)As for the 'rotate' functions, they should really set every element of the matrix to the appropriate value, rather than making assumptions about the previous state of the matrix (IMO). Also, I don't see you setting the matrix to identity anywhere in your code - are you sure it's set to identity before the rotation functions are called? Are you setting the matrix to identity and then making multiple calls to the rotation functions with the expectation that the rotations will accumulate in some way?

I haven't made it represent nothing, as I just wanted to ball to move and look correct never was concerned with realistic movements or simulations on the ball. So velocity is just another name for speed...

Yes, I am calling Identity() and I changed the velocity to speed to clear up this isn't a vector I am using and starting to think I need a vector for my fwd movement and side to side to get this to work????

//Draw Player	scaleMatrix.Identity();	rotMatrix.Identity();	matrix.Identity();	glPushMatrix();			if(playerRight || playerLeft)		{			rotMatrix.ArbitraryRotation(NX::MATH::DegToRad(angle) * speedClamped, 1, 1, 1);//			rotMatrix.RotateX(NX::MATH::DegToRad(angle) * speedClamped * .1f);		}		else		{			rotMatrix.ArbitraryRotation(NX::MATH::DegToRad(angle) * speed, 1, 1, 1);//			rotMatrix.RotateX(NX::MATH::DegToRad(angle) * speed * .001f);		}				scaleMatrix.Scale(playerScale, playerScale, playerScale, true, true, true);		playerPos = playerTransformMatrix & NX::MATH::vec3<float>(0.0f, 0.0f, playerDir);		matrix.Translate(playerPos);		playerSphere.UpdateCenter(matrix);		matrix *=scaleMatrix;		matrix *=rotMatrix;		glMultMatrixf(matrix.matrix);		DrawBall();	glPopMatrix();

##### Share on other sites
KOzymandias    132
I can understand how to use ArbitraryRotation() with only one angle and one 'true', like it was in the first post. But I think it can't be used with 3 'true/1'. What's it gonna do, rotate around x, then y, then z by angle radian ?

Why don't you just use 3 rotation matrices like this ?
Matrix4 rotX, rotY, rotZ, rotYXZ;rotX.SetRotationX(angle_x);rotY.SetRotationY(angle_y);rotZ.SetRotationZ(angle_z);rotXYZ = rotX * rotY * rotZ; // or rather rotY * rotX * rotZ;

Then if you want, you can code a RotateXYZ functions that takes 3 angles (and no bool, an angle of 0 is enough) and makes rotXYZ without intermediary matrices, but at least it's more clear what the resulting matrix is. Note that you probably don't need the rotY matrix since you only need to go forward and on the side.

##### Share on other sites
MARS_999    1627
Quote:
 Original post by KOzymandiasI can understand how to use ArbitraryRotation() with only one angle and one 'true', like it was in the first post. But I think it can't be used with 3 'true/1'. What's it gonna do, rotate around x, then y, then z by angle radian ? Why don't you just use 3 rotation matrices like this ?*** Source Snippet Removed ***Then if you want, you can code a RotateXYZ functions that takes 3 angles (and no bool, an angle of 0 is enough) and makes rotXYZ without intermediary matrices, but at least it's more clear what the resulting matrix is. Note that you probably don't need the rotY matrix since you only need to go forward and on the side.

I will try it later, but will this solve my issue at hand with the ball rotating correctly when moving side to side and side+fwd?