## Rotating a triangle to vertical.

Nibbie
Posts: 2
Joined: 2010.11
Post: #1
Hi,
I have two 3D triangles. I would like to rotate the first triangle so that its normalized normal is (0,0,1) (2D) and then preform the same operation on the second triangle. I have the normal of triangle 1 in a vector. I would prefer to do this using vector and matrix math rather than trig for speed reasons. Is there any way to do this that comes to the minds of any here further down the road in math than I am?

Thanks!
Moderator
Posts: 1,563
Joined: 2003.10
Post: #2
axis = crossProduct(currentNormal, {0, 0, 1})
angle = acos(dotProduct(currentNormal, {0, 0, 1}))
rotation = QuaternionFromAxisAngle(axis, angle)

You'll have to special case the situations where the triangle is facing {0, 0, 1} or {0, 0, -1}, or very close to it. This should work for everything else.
Member
Posts: 142
Joined: 2002.11
Post: #3
Joseph Duchesne Wrote:Hi,
I have two 3D triangles. I would like to rotate the first triangle so that its normalized normal is (0,0,1) (2D) and then preform the same operation on the second triangle. I have the normal of triangle 1 in a vector. I would prefer to do this using vector and matrix math rather than trig for speed reasons. Is there any way to do this that comes to the minds of any here further down the road in math than I am?

Thanks!

Here is a function you could use in case you don't want to use ThemsAllTook's Quaternion approach (I'm not dissing Quaternions here, I just happen to have this code available). Get the angle and axis as he does, and then pass your vectors to this function to be rotated:
/*
Rotates a vector amt about a given axis in the counter clockwise direction
v is the vector to be rotated
axis is the axis of rotation
amount is the angle to be rotated (in radian measure)
*/
vector3 rotate_about_axis(const vector3 &v, const vector3 &axis, float amount) {
float cos_amount = cos(amount);
vector3 n_axis = normalize(axis);
vector3 part1 = cos_amount * v;
vector3 part2 = (1.0f - cos_amount) * (dot(axis, v)) * n_axis;
vector3 part3 = sin(amount) * cross(v, n_axis);
return part1 + part2 + part3;
}
Member
Posts: 131
Joined: 2004.10
Post: #4

Take one vector of the triangle, normalize it. That will be our up vector. (w)
Take the normal of the triangle. Basically crossing our chosen vector above with the next vector in the triangle. Make sure the result is normalized. (u)
Cross the two to get the third vector for our coordinate system. Normalize for good measure. (v)

Matrix =
(u.x v.x w.x 0
u.y v.y w.y 0
u.z v.z w.z 0
0 0 0 1)

Now multiply the triangle with this matrix and voila. (Note you may need to transpose the matrix depending on how you multiply.)
Member
Posts: 142
Joined: 2002.11
Post: #5

Take one vector of the triangle, normalize it. That will be our up vector. (w)
Take the normal of the triangle. Basically crossing our chosen vector above with the next vector in the triangle. Make sure the result is normalized. (u)
Cross the two to get the third vector for our coordinate system. Normalize for good measure. (v)

Matrix =
(u.x v.x w.x 0
u.y v.y w.y 0
u.z v.z w.z 0
0 0 0 1)

Now multiply the triangle with this matrix and voila. (Note you may need to transpose the matrix depending on how you multiply.)

This won't work.

There are two problems with it. First, the columns of the matrix are given in the wrong order. Joseph wants the normal to map to (0,0,1). This means u must be the third column, not first, since u represents the triangle's normal. Secondly, the matrix inverse must be taken. If the columns are interchanged as I said, then (0,0,1) would map to the normal, but we want the reverse - that the normal be mapped to (0,0,1).

There is one thing I want to point out to Joseph at this point:

There are an infinite number of rotations which will map the normal vector of the triangle to (0,0,1). This condition alone does not determine a rotation, because once you rotate the triangle to (0,0,1) you can rotate about the normal vector and produce what would also be a valid rotation.

ThemsAllTook's method has the property that when the triangle is rotated, it is not rotated at all about its normal. This may be desirable, depending on what you're doing. Zekaric's method (once fixed) will produce a rotation which does what you asked, but has the side effect of rotating one side of the triangle to the vertical. Zekaric's method is simpler, but I don't know that you want the side effect that comes with it.

In short ... tell us more about what you're doing.
Sage
Posts: 1,403
Joined: 2005.07
Post: #6
I am just really curious but, do you mind me asking what this calculation is for?

Sir, e^iÏ€ + 1 = 0, hence God exists; reply!