Jump to content
  • Advertisement
Sign in to follow this  
mike74

3d rotation

This topic is 4727 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

Hey guys. I'm trying to develop a 3d rotation function in Java. Basically, I want to pass a point to it, an axis, and an angle and have it rotate the point about the axis and origin. The function is in Java and will look like this: public void(double[] vertices, double axisx, double axisy, double axisz, double theta) { } The "vertices" parameter is an array of 3 coords - x, y, and z. When the function is done they will be modified to be the rotated x, y, and z. Basically, I think I need to create some kind of 3x3 matrix from the axis values and theta. Then, I need to multiply the vertices by that. However, I'm not sure what values go in the 3x3 matrix. If anyone can point me in the right direction, I'd appreciate it. Mike C. http://www.coolgroups.com/zoomer/

Share this post


Link to post
Share on other sites
Advertisement
How about writing a vector class with the private double values x, y and z?
And why call the one parameter vertices even though it can only store one vertex?

Your parameter list could then be:
public void rotate(vector* vertexPos, vector* axisDirection, double theta)

My disclaimer ... the last time I tried implementing a camera class and rotations and that stuff I failed.

Guess the better approach would be not only rotating that one point but all points around the axis ... like glRotatef does it?
Do you have a global 4x4 matrix that you can multiply with a rotation matrix and a scene graph?

I'll just assume you want to rotate all the points manually by calling that function.
Guess the 3x3 matrix wouldn't be that interesting ... usually there are up, side and look vectors in it.
Your point doesn't have such vectors.
For the position vector you'd need the 4x4 matrix afaik.

Correct me if I'm wrong, guys.

Share this post


Link to post
Share on other sites
The equation to rotate a vector 'v' about a unit-lenth vector 'n' is:

v' = (v.n)n + cos(theta)(v-(v.n)n) + sin(theta)(nXv)

If you just want to rotate a couple of vectors you can use the equation directly, but as you noted it can be useful to convert it to matrix form instead. You can find the matrix yourself by working through the math, or google for 'axis angle matrix' to find the standard form. Be aware that there are different conventions and if you get the matrix from online, the direction of your rotations may be the reverse of what you expect; transposing the matrix should fix this.

Share this post


Link to post
Share on other sites
You're right that I should call it vertex and not vertices. I'm not passing in a vector class because I don't feel like writing one until I get it working. Anyhow, I've attached my function, but it seems to work only some of the time. If anyone can tell me what's wrong, I'd be very grateful.

Also, I wasn't sure whether or not the rotation matrix was for multiplying by a 3x1 matrix or a 1x3 matrix of x, y, z values. Anyone know? Either way sort of works, but doesn't work completely. Sometimes the rotations look a bit off when I render them in my raytracer.


private void rotate(double vertex[], double x, double y, double z, double theta)
{
double[][] rm = new double[3][3];

double c = Math.cos(theta);
double s = Math.sin(theta);
double t = 1 - Math.cos(theta);

rm[0][0] = t*x*x + c;
rm[1][0] = t*x*y - s*z;
rm[2][0] = t*x*z + s*y;

rm[0][1] = t*x*y + s*z;
rm[1][1] = t*y*y + c;
rm[2][1] = t*y*z - s*x;

rm[0][2] = t*x*z - s*y;
rm[1][2] = t*y*z + s*x;
rm[2][2] = t*z*z + c;

//vertex[0] = vertex[0]*rm[0][0] + vertex[1]*rm[0][1] + vertex[2]*rm[0][2];
//vertex[1] = vertex[0]*rm[1][0] + vertex[1]*rm[1][1] + vertex[2]*rm[1][2];
//vertex[2] = vertex[0]*rm[2][0] + vertex[1]*rm[2][1] + vertex[2]*rm[2][2];


vertex[0] = vertex[0]*rm[0][0] + vertex[1]*rm[1][0] + vertex[2]*rm[2][0];
vertex[1] = vertex[0]*rm[0][1] + vertex[1]*rm[1][1] + vertex[2]*rm[2][1];
vertex[2] = vertex[0]*rm[0][2] + vertex[1]*rm[1][2] + vertex[2]*rm[2][2];


}


Mike C.
http://www.coolgroups.com/zoomer/

Share this post


Link to post
Share on other sites
Never mind, I figured it out.

Here's some code that seems to work:

public void rotate(double vertex[], double x, double y, double z, double theta)
{
double[][] rm = new double[3][3];

double c = Math.cos(theta);
double s = Math.sin(theta);
double t = 1 - Math.cos(theta);

rm[0][0] = t*x*x + c;
rm[1][0] = t*x*y - s*z;
rm[2][0] = t*x*z + s*y;

rm[0][1] = t*x*y + s*z;
rm[1][1] = t*y*y + c;
rm[2][1] = t*y*z - s*x;

rm[0][2] = t*x*z - s*y;
rm[1][2] = t*y*z + s*x;
rm[2][2] = t*z*z + c;

double[] newvertex = new double[3];

newvertex[0] = vertex[0]*rm[0][0] + vertex[1]*rm[0][1] + vertex[2]*rm[0][2];
newvertex[1] = vertex[0]*rm[1][0] + vertex[1]*rm[1][1] + vertex[2]*rm[1][2];
newvertex[2] = vertex[0]*rm[2][0] + vertex[1]*rm[2][1] + vertex[2]*rm[2][2];

//vertex = newvertex;

vertex[0] = newvertex[0];
vertex[1] = newvertex[1];
vertex[2] = newvertex[2];

//vertex[0] = vertex[0]*rm[0][0] + vertex[1]*rm[1][0] + vertex[2]*rm[2][0];
//vertex[1] = vertex[0]*rm[0][1] + vertex[1]*rm[1][1] + vertex[2]*rm[2][1];
//vertex[2] = vertex[0]*rm[0][2] + vertex[1]*rm[1][2] + vertex[2]*rm[2][2];


}

As you may have noticed, I'm still not sure whether the x,y,z vector is a 3x1 or 1x3 matrix. If someone could throw some edifying verbiage at me, I'd appreciate it.

Thanks.

Mike C.
http://www.coolgroups.com/zoomer/

Share this post


Link to post
Share on other sites
Quote:
As you may have noticed, I'm still not sure whether the x,y,z vector is a 3x1 or 1x3 matrix.
Here's what it looks like to me. The top (uncommented) multiplication treats the vector as a column (3x1) vector. The bottom (commented out) multiplication treats the vector as a row (1x3) vector.

Assuming that the handedness of your coordinate system and rotations match, the matrix looks like it is intended to be used with row vectors. So at this point you may be constructing a row-vector matrix, but performing a column-vector multiplication, which may cause the rotations to be the reverse of what you expect.

Other than that, though, everything looks correct.

Share this post


Link to post
Share on other sites
In what sense, do you believe the rotations are reversed? For instance, if I rotate by 45 degrees, do you think it does -45 degrees?

Thanks.



Mike C.
http://www.coolgroups.com/zoomer/

Share this post


Link to post
Share on other sites
As far as I know there are four things you have to take into consideration when formulating your rotation matrix:

1. Coordinate system handedness
2. Rotation handedness
3. Row or column vector convention
4. Row- or column-major convention

It looks like number 4 may not be relevant in your case. If you can specify what your desired convention is for numbers 1, 2, and 3, you can determine how to correctly set up your rotation matrix. (If you're unsure about any of the terminology I'll be glad to clarify.)

Getting rotations to be 'correct' is tricky. Quite often we get a matrix from some reference without fully understanding it, and plug it into our code. We try assigning, say, a negative roll to the left arrow key, and find that it rotates the wrong way. So instead we assign a positive roll to the left arrow, and viola, it works, although we may not understand exactly way. But again, if you can clearly determine all the conventions that you are using, you can determine the correct formulation of your rotation matrix.

Share this post


Link to post
Share on other sites
jyk, you're right about the rotations being reversed. That's a very counterintuitive result for me. I expected some really weird stuff to happen if I used a row matrix when it should have been a column matrix, or vice versa.

Just out of curiosity, do you know what happens in the 4x4 case (with rotation, scaling, and translation)?

Thanks.

Mike C.
http://www.coolgroups.com/zoomer/

Share this post


Link to post
Share on other sites
Quote:
Just out of curiosity, do you know what happens in the 4x4 case (with rotation, scaling, and translation)?
I think the short answer is that multiplying a 4x4 matrix intended to be used with row vectors with a column vector, or vice versa, will not produce particularly meaningful results. (As always, there could be some use for this that I'm not aware of...)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!