Sign in to follow this  
WDonnelly

Rotating a Vector

Recommended Posts

I'm making a 3D game, and the objects need to be able to rotate. I want to rotate a vector on 3 different axes, with just 2 points and 3 angles (for each axis). currently, the code goes:
int checkcollision (double ox1, double oy1, double oz1, double ox2, 
		    double oy2, double oz2) {

	int cx,cy,cz;

	cx = ck(x1,x2,ox1,ox2);
	cy = ck(y1,y2,oy1,oy2);
	cz = ck(z1,z2,oz1,oz2);
	if(cx+cy+cz==3){return 1;}
	return 0;

}

(x1,y1,z1) and (x,y2,z2) are the two necessary coordinates for the box which is being tested. (ox1,oy1,oz1) et al are the vector representing the player's movement. the ck() function just does the detection with the 4 given values. o1 won't always be (0,0,0), further complicating matters I already have code that does similar things on just x and z axes with just 1 axis of rotation, but, being still in middle school, I haven't yet learned to understand the sin() and cos() function's uses. despite many google searches, the closest I could find was this thread on how to do it in 2d, but I screwed up trying to get the other rotations right.

Share this post


Link to post
Share on other sites
Quote:
Original post by WDonnelly
I'm making a 3D game, and the objects need to be able to rotate.
I want to rotate a vector on 3 different axes, with just 2 points and 3 angles (for each axis).
...
I already have code that does similar things on just x and z axes with just 1 axis of rotation

If you have the angles with each of the axes, you could rotate 3 times with the code you already have, once for each axis.

But, I don't think that's very efficient or elegant. The usual way of doing arbitrary rotation is to take one 3d vector which is the axis around which rotation will occur. After that you need just one angle to rotate your vector. This rotation can be done using matrices (search for 'transformation matrices' for more info).

In fact, I have some code lying about that rotates a vector about an arbitrary axis / angle. Here it is:


void vec3::rotate (float theta, vec3 axis)
{
vec3 ret;

float costheta = std::cos (theta * PI_OVER_180);
float sintheta = std::sin (theta * PI_OVER_180);

ret.x = (this->x * ((1 - costheta) * axis.x * axis.x + costheta) +
this->y * ((1 - costheta) * axis.x * axis.y - (sintheta * axis.z)) +
this->z * ((1 - costheta) * axis.z * axis.x + (sintheta * axis.y)));

ret.y = (this->y * ((1 - costheta) * axis.y * axis.y + costheta) +
this->z * ((1 - costheta) * axis.y * axis.z - (sintheta * axis.x)) +
this->x * ((1 - costheta) * axis.x * axis.y + (sintheta * axis.z)));

ret.z = (this->z * ((1 - costheta) * axis.z * axis.z + costheta) +
this->x * ((1 - costheta) * axis.z * axis.x - (sintheta * axis.y)) +
this->y * ((1 - costheta) * axis.y * axis.z + (sintheta * axis.x)));

*this = ret;
}





To see how it works, read this article (scroll down, part II).

Share this post


Link to post
Share on other sites
Okay, I'm feeling really stupid now, as I couldn't understand that article either.
Using the function posted above would be tricky, as I wouldn't know how to convert it into a rotation around just one vector.
I think I figured out what I should be doing, though. My rotate function might work now (I wrote a little test program to develop the function, and it delivered the right results there), but now I just have problems with signedness and such. Or maybe I am doing it wrong:


void rotate(float ox, float oy, float oz, float rotx, float roty, float rotz){
float tmpx = 0;
float tmpy = 0;
float tmpz = 0;

tmpx += (ox*cos(roty*piover180)) * (ox*cos(rotz*piover180));
tmpy += (oy*cos(rotx*piover180)) * (oy*cos(rotz*piover180));
tmpz += (oz*cos(rotx*piover180)) * (oz*cos(roty*piover180));

tmpx += (oz*sin(roty*piover180)) + (oy*sin(rotz*piover180));
tmpy += (oz*sin(rotx*piover180)) + (ox*sin(rotz*piover180));
tmpz += (oy*sin(rotx*piover180)) + (ox*sin(roty*piover180));

rvout[1]=tmpx;
rvout[2]=tmpy;
rvout[3]=tmpz;
}



As you can see, the first clump initializes the variables, the second one uses cosine to decrease the ones that turn, the third block uses sine to determine what gets longer, and the last one sets a few variables that I'm using to store the output.

According to the graph of a sine and cosine drawn on my arm, this should work. Did I mistype or make some stupid little mistake?

Share this post


Link to post
Share on other sites
Actually, it's quite possible to do what you are trying with thazt code:

vec3 player (ox, oy, oz); // did I interpret that right?

vec3 xaxis (1, 0, 0);
vec3 yaxis (0, 1, 0);
vec3 zaxis (0, 0, 1);

player.rotate (rotx, xaxis);
player.rotate (roty, yaxis);
player.rotate (rotz, zaxis);



I'm sorry, but I don't really get how you derived that function for rotation. The first bit--you are taking the projection on the other axes ... but after that you lost me. [smile]

It is simple to do one axis rotation with the concept of polar coordinates in 2D. This page - link has some info.

Share this post


Link to post
Share on other sites
Okay, I feel stupid. The code worked perfect. The error was in my level file: I was placing the player INSIDE the floor, but the view offset kept me from noticing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this