0
101 Feb 01, 2003 at 00:33

i’ve been beating around the bush about this topic for a while now and I wanted to know how to go about 3D space. [bare with me]

my problem is with complete 360 degree rotations about 3D space. I tried trig functions sin and cos to rotate about a plane and that works fine but in 3D space it only works on the ‘positive’ quadrants. I tried vector manipulations (cross product of a general UP vector with the forward vector to get the “left-right” orientation and then crossing the left-right vector with the forward to get the “up-down” vector…). now i’m back to trig functions in combination with spherical coords and i run to a similar problem [one of the ‘axis’ remains positive]. anybody got any hints?

I also wanted to grease the wheels of just having a theoretical discussion about anything game-related: from cool effects, AI, whatever.

thanks

#### 14 Replies

0
101 Feb 01, 2003 at 14:38

The functions below will take a vector argument, and the number of degrees to rotate that vector (could use the vector as the movement, or looking, whatever) they return the new vector after being rotated. 2 things to note, first the vector MUST be normalized. Second, you must know which way you want to rotate, IE, left or right around the axis you want to rotate around, or you could simply always rotate left, but instead of rotating 30 right, you simply rotate 330 left. Get it? Oh, by the way, the vector rotated will not have an up. Meaning, if you rotate the vector 0,0,-1 around the z axis, it wont change, thus if your using a viewing angle with this, you should probly also create an UP vector and rotate that as well, to determin which way is up.

Hope this is what you were looking for.

struct VectorStruct
{
float X, Y, Z;
}

VectorStruct RotateLeftXAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.Z = TempV1.Z * (cos(Degrees*PI/180)) + TempV1.Y * (sin(Degrees*PI/180));
V1.Y = TempV1.Y * (cos(Degrees*PI/180)) - TempV1.Z * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateLeftYAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.X = TempV1.X * (cos(Degrees*PI/180)) + TempV1.Z * (sin(Degrees*PI/180));
V1.Z = TempV1.Z * (cos(Degrees*PI/180)) - TempV1.X * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateLeftZAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.Y = TempV1.Y * (cos(Degrees*PI/180)) + TempV1.X * (sin(Degrees*PI/180));
V1.X = TempV1.X * (cos(Degrees*PI/180)) - TempV1.Y * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateLeftAllAxis(VectorStruct V1, float Degrees[])
{
V1 = RotateLeftXAxis(V1, Degrees[x]);
V1 = RotateLeftYAxis(V1, Degrees[y]);
V1 = RotateLeftZAxis(V1, Degrees[z]);

return V1;
}

VectorStruct RotateRightXAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.Z = TempV1.Z * (cos(Degrees*PI/180)) - TempV1.Y * (sin(Degrees*PI/180));
V1.Y = TempV1.Y * (cos(Degrees*PI/180)) + TempV1.Z * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateRightYAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.X = TempV1.X * (cos(Degrees*PI/180)) - TempV1.Z * (sin(Degrees*PI/180));
V1.Z = TempV1.Z * (cos(Degrees*PI/180)) + TempV1.X * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateRightZAxis(VectorStruct V1, float Degrees)
{
VectorStruct TempV1;

if(Degrees < 0)
{
Degrees = 360 + Degrees;
}

TempV1 = V1;

V1.Y = TempV1.Y * (cos(Degrees*PI/180)) - TempV1.X * (sin(Degrees*PI/180));
V1.X = TempV1.X * (cos(Degrees*PI/180)) + TempV1.Y * (sin(Degrees*PI/180));

return V1;
}

VectorStruct RotateRightAllAxis(VectorStruct V1, float Degrees[])
{
V1 = RotateRightXAxis(V1, Degrees[x]);
V1 = RotateRightYAxis(V1, Degrees[y]);
V1 = RotateRightZAxis(V1, Degrees[z]);

return V1;
}

0
158 Feb 01, 2003 at 20:29

Have you tried using Quaternions? Using angle anaylsis to do rotations is a headache. Your best solution to doing it is either use Matrices or Quaternions. I recommend using Quaternions since they are faster. If you want details on that, let me know, and I’ll post some code.

0
101 Feb 01, 2003 at 23:32

ran across quaternions. don’t know what they are - sounds interesting. yeah if you want, post some. if it’s too much, links would be cool.

thanks

0
101 Feb 02, 2003 at 17:04

looked up what i could about quarternions [still looking]. anybody got any good links?

0
101 Feb 02, 2003 at 18:02

Perhaps the tutorial at Game Tutorials may help.

http://www.gametutorials.com/Tutorials/ope…/OpenGL_Pg4.htm

4th tutorial down on the page.

0
101 Feb 04, 2003 at 03:05

hey thanks [[b]apex[/b], [b]woz[/b]] for the suggestion. quaternion solved my problem. had to read a lot of people’s interpretation until finding a course-site from ucla berkely which made a lot of sense. learned a lot and applied it.

again, thanks.

0
101 Feb 04, 2003 at 16:08

thanks to you to dabeav but the above code still placed me in a “gimbal lock”. hehe see how much I learned from quaternions? the code provided a solution, something I was looking for, but I also wanted substance and why it worked.

at any rate i really appreciate everybody’s input.

again, thanks.

0
101 Feb 05, 2003 at 08:00

@donBerto

thanks to you to dabeav but the above code still placed me in a “gimbal lock”. hehe see how much I learned from quaternions? the code provided a solution, something I was looking for, but I also wanted substance and why it worked.

at any rate i really appreciate everybody’s input.

again, thanks.

whats a gimbal lock? anyway, could you post the link to the ucla site that explains quaternions.. thanks :)

0
101 Feb 05, 2003 at 12:45

sure.

rough definition of gimbal lock: calculation of some angles may ‘override’ another, preventing an angle from being positive/negative or whatever.

good definition: http://www.gamedev.net/reference/articles/…article1095.asp
[third blue heading down the page].

and excuse me, the site is from UCberkely, not UCLA. sorry. here:

http://www.cs.berkeley.edu/\~laura/cs184/qu…quaternion.html

an example of gimbal lock [similar to what I encountered]:

struct vector
{
float x, y, z;
};

void func(float horizAngle, float vertAngle)
{
vector forwardv;

// looking up and down
forwardv.z = cos(vertAngle); // first z calculation
forwardv.y = sin(vertAngle);

// looking left and right
forwardv.x = cos(horizAngle);
forwardv.z = sin(horizAngle); // gimbal lock - overrides first z's calculation
}


i hope this will helpl people in the long-run.

cheers,
-berto

0
101 Feb 08, 2003 at 15:20

I googled for a while on more quaternions and found this really informative site for us who have little time/patience ;)

reading through it now and I’m finding it very useful. I hope it is for you too.

here it is:

0
101 Feb 08, 2003 at 15:45

That link also has some other interesting items on his other pages.

http://skal.planet-d.net/demo/matrixfaq.htm

sub-pixel interpolation for motion estimation.
Two Convex Hull algorithms for finding good bounding slabs

Just to name a few, but many more.

0
101 Feb 12, 2003 at 02:32

I dont believe that above code snippet will ever create a Gimble lock. Because it uses a temp variable so that the rotation of one axis dosnt over ride the other axis, upon compleation. Thus things dont go negative. I have yet to have any problems with it any ways, if someone could come up with an instance that the above code dosnt work, let me know. I will have to run some calcs to figure that out, and see if it is possible with that code.

0
101 Feb 15, 2003 at 07:44

to dabeav:

using your implementation i had some time to test and i’m still testing. so far, here’s the lock. THE MISTAKE COULD BE IN MY END:

individual rotation works great. so far, the only case i have is when i rotate 90 degrees about the y axis and then rotating about the x axis – instead of looking up and down, it looks “roll-left” to “roll-right” – z rotation.

but like i said, the error could be on my part I have a forward vector [using your vector struct] and then i cross with a global up to get the side axis. I then cross forward with side to get the relative up axis. i place the 3 vectors in a matrix and glMultMatrix.

let’s beat the hell out of this problem so that no one will ever have to go through with it :yes:

0
101 Feb 22, 2003 at 23:20

I fixed my problem. in one of the demos [can’t remember] the programmer used euler angles and I mistook them as vectors.

thanks for everybody’s support. I appreciate that a lot.
:yes: