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
Click For Summary

Discussion Overview

The discussion revolves around implementing a function in C++ to rotate a 3D vector using a specified rotation axis (norm vector) and angle. Participants explore various methods for achieving this transformation, including the use of rotation matrices and quaternions.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant requests guidance on how to rotate a 3D vector given a rotation axis and angle, providing a formula for the transformation.
  • Another participant suggests using either a rotation matrix or quaternions for the rotation, mentioning that quaternions may offer more flexibility for interpolating between rotations.
  • A participant expresses a preference for using quaternions but aims to simplify the process by substituting them into a rotation matrix instead of creating a separate quaternion class.
  • Details of creating a quaternion and the corresponding rotation matrix are shared, including the normalization of the rotation axis and the multiplication of the matrix with the vector.
  • One participant adds that if the rotation is around an arbitrary point, additional translation steps are necessary before and after the rotation.
  • Another participant clarifies that their goal is to rotate a homogeneous magnetic field, suggesting that the complexity of rotating around a point is unnecessary for their application.
  • A different approach is proposed, detailing a method to compute the rotated vector using the rotation axis and angle directly, which is presented as potentially more efficient than building a rotation matrix.

Areas of Agreement / Disagreement

Participants present multiple methods for vector rotation, including rotation matrices and quaternions, without reaching a consensus on the best approach. Some express preferences for simpler methods, while others highlight the benefits of more complex solutions.

Contextual Notes

Participants note that the effectiveness of the discussed methods may depend on the specific application, such as whether the rotation is around the origin or an arbitrary point. Additionally, the computational efficiency of different methods is considered, particularly in the context of repeated rotations.

Who May Find This Useful

This discussion may be useful for C++ developers working on simulations or graphics programming that involve 3D vector manipulations, particularly in physics or game development contexts.

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 :-)
 
Physics 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 :)
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 15 ·
Replies
15
Views
3K
  • · Replies 3 ·
Replies
3
Views
5K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
8
Views
1K
  • · Replies 1 ·
Replies
1
Views
4K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K