How can I rotate a 3D vector using a norm direction and angle in C++?

  • Thread starter Thread starter TheDestroyer
  • Start date Start date
  • Tags Tags
    Origin Rotation
AI Thread Summary
To rotate a 3D vector in C++, the discussion highlights two primary methods: using rotation matrices or quaternions. The suggested approach involves normalizing the rotation axis vector and creating a quaternion based on the rotation angle. A rotation matrix is then derived from the quaternion, which can be used to transform the initial vector. Additionally, for rotating around an arbitrary point, a translation step is necessary before and after the rotation. The conversation emphasizes efficiency, suggesting that for single rotations, directly using the rotation axis may be simpler and faster.
TheDestroyer
Messages
401
Reaction score
1
I have a C++ class for a math vector. I would like to add a function that rotates this vector in 3D, so that the user could input the direction of rotation as a norm vector, and the angle with which he would like to rotate, and have the function automatically rotate the initial vector for him and return the new 3 components.

What's the way to do it? could you guys please provide me with this transformation as

v'(vx',vy',vz') = f(θ,a,b,c,v(vx,vy,vz))

Where θ is the angle, a,b,c, is the norm to rotation direction, and v is the initial vector, and v' is the rotated vector.

Thank you for any efforts :-)
 
Mathematics news on Phys.org
TheDestroyer said:
I have a C++ class for a math vector. I would like to add a function that rotates this vector in 3D, so that the user could input the direction of rotation as a norm vector, and the angle with which he would like to rotate, and have the function automatically rotate the initial vector for him and return the new 3 components.

What's the way to do it? could you guys please provide me with this transformation as

v'(vx',vy',vz') = f(θ,a,b,c,v(vx,vy,vz))

Where θ is the angle, a,b,c, is the norm to rotation direction, and v is the initial vector, and v' is the rotated vector.

Thank you for any efforts :-)

Hey TheDestroyer.

In terms of rotating vectors, you can do it using a matrix or you can use what is known as quaternions.

If you want to do rotations where you 'interpolate' between rotations then my advice is to implement a quaternion class and then convert the representation to a matrix. If you don't need this much flexibility then just use a matrix class. In terms of the actual implementation you can use existing code (search and you'll find dozens of implementations) or if you want to code up your own use this formula:

http://en.wikipedia.org/wiki/Axis-angle_representation#Rotating_a_vector

For quaternions, again search the internet for quaterion classes. You should get tonnes of hits. If you don't look up any decent open source game engine and there should be a quaternion and matrix class: Also Intel have optimized routines for various matrix routines using SSE and SSE2 instructions. I promise you there are tonnes of implementations already shared and use google to find them.

In terms of the way to do this:

1) Create rotation matrix M
2) Transform vector by calculating v' = Mv
3) v' is rotated vector.
 
Thanks a lot for your answer, chiro.

I would not like to complicate stuff by creating a Quaternion class, but I could use the quaternion and substitute it in the rotation matrix. It's apparently just simpler.

So what I got is the following: To rotate a vector v(vx,vy,vz) around a vector w(wx,wy,wz) with the angle θ I do the following:

1. Normalize w (from now on w is normalised)
2. Create the quaternion:

q0 = Cos[θ/2]
q1 = Sin[θ/2]*wx
q2 = Sin[θ/2]*wy
q3 = Sin[θ/2]*wz

3. Create the rotation matrix from that:


\begin{array}{ccc}
\text{q0}^2+\text{q1}^2-\text{q2}^2-\text{q3}^2 & 2 \text{q1} \text{q2}-2 \text{q0} \text{q3} & 2 \text{q0} \text{q2}+2 \text{q1} \text{q3} \\
2 \text{q1} \text{q2}+2 \text{q0} \text{q3} & \text{q0}^2-\text{q1}^2+\text{q2}^2-\text{q3}^2 & -2 \text{q0} \text{q1}+2 \text{q2} \text{q3} \\
-2 \text{q0} \text{q2}+2 \text{q1} \text{q3} & 2 \text{q0} \text{q1}+2 \text{q2} \text{q3} & \text{q0}^2-\text{q1}^2-\text{q2}^2+\text{q3}^2
\end{array}

4. Multiply it with the vector.

Hope it's right :-) Please confirm that!
 
TheDestroyer said:
Thanks a lot for your answer, chiro.

I would not like to complicate stuff by creating a Quaternion class, but I could use the quaternion and substitute it in the rotation matrix. It's apparently just simpler.

So what I got is the following: To rotate a vector v(vx,vy,vz) around a vector w(wx,wy,wz) with the angle θ I do the following:

1. Normalize w (from now on w is normalised)
2. Create the quaternion:

q0 = Cos[θ/2]
q1 = Sin[θ/2]*wx
q2 = Sin[θ/2]*wy
q3 = Sin[θ/2]*wz

3. Create the rotation matrix from that:


\begin{array}{ccc}
\text{q0}^2+\text{q1}^2-\text{q2}^2-\text{q3}^2 & 2 \text{q1} \text{q2}-2 \text{q0} \text{q3} & 2 \text{q0} \text{q2}+2 \text{q1} \text{q3} \\
2 \text{q1} \text{q2}+2 \text{q0} \text{q3} & \text{q0}^2-\text{q1}^2+\text{q2}^2-\text{q3}^2 & -2 \text{q0} \text{q1}+2 \text{q2} \text{q3} \\
-2 \text{q0} \text{q2}+2 \text{q1} \text{q3} & 2 \text{q0} \text{q1}+2 \text{q2} \text{q3} & \text{q0}^2-\text{q1}^2-\text{q2}^2+\text{q3}^2
\end{array}

4. Multiply it with the vector.

Hope it's right :-) Please confirm that!

I haven't confirmed the details of the matrix but yeah that should that work.

Also just one thing I need to add: if it is around the origin then the above should work. If you need to rotate it about an arbitrary point, then you need to translate the vector first by the negative of this point, rotate it, and then translate it back. You can use matrices to do transformations and then you can just compose the matrices to get your final transformation matrix.

This will be useful to know if you end up doing transformations that are hierarchical like for example modelling things like human movement (hands connected to arms connected to torso kinda thing) or doing some kind of modelling like say a solar system (circular orbits). If you want to create a general dynamics system of some sort, then you will have to do this (think about when you have check a chain through the air and each link is effect the motion of the entire chain).
 
Actually what I want to rotate is simply a homogeneous magnetic field for a simulation. I think that thing with the point isn't necessary, since it's a homogeneous vector field.

Thanks a lot, buddy :-)

Have a nice day!
 
If all you want to do is one rotation it's faster and easier to use the rotation axis as a vector. Suppose \vec v is the vector you want to rotate, \hat u is the unit vector along the rotation axis, and \theta is the rotation angle.

Define
\begin{aligned}<br /> \vec v_1 &amp;= (\hat u \cdot \vec v)\hat u \\<br /> \vec v_3 &amp;= \hat u \times \vec v \\<br /> \vec v_2 &amp;= \vec v - \vec v_1<br /> \end{aligned}

(Note that \vec v_2 = \vec v_3 \times \hat u, but computing via subtraction is a lot faster.)

The rotated vector is simply
\vec v_{u,\theta} = \vec v_1 + \cos\theta\,\vec v_2 + \sin\theta\,\vec v_3

The total cost is 18 multiplies, 14 adds. Building the rotation matrix alone costs that much. Once you have the rotation matrix, using it only costs 9 multiplies, 6 adds. If you are going to reuse the same rotation more than twice it pays off to create and use the matrix.
 
Thanks a lot, D H. I'm going to try that :)
 
Back
Top