How to rotate a vector about an Arbitrary Axis in 3D to align two vectors?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












What I'm trying to do...



Say I have two vectors. I want to align these vectors so that they one of my vectors is pointing directly at the other. For example, imagine there is this point and I want to position my camera so that my camera's center is directly aligned with said point.



From my understanding to do this, I would calculate the cross product between the two vectors and use that as an arbitrary axis of rotation.



From there I would need an angle $theta,$ which can be determined by taking the dot product between the two vectors and dividing by the product of their magnitudes. Then I would solve for $theta$ using $cos^-1$



$$theta=cos^-1$$



I'm stuck on how to determine the appropriate rotation matrix which to rotate about.



Also, I'm not sure if my process is correct I was looking online to figure this out.







share|cite|improve this question

























    up vote
    0
    down vote

    favorite












    What I'm trying to do...



    Say I have two vectors. I want to align these vectors so that they one of my vectors is pointing directly at the other. For example, imagine there is this point and I want to position my camera so that my camera's center is directly aligned with said point.



    From my understanding to do this, I would calculate the cross product between the two vectors and use that as an arbitrary axis of rotation.



    From there I would need an angle $theta,$ which can be determined by taking the dot product between the two vectors and dividing by the product of their magnitudes. Then I would solve for $theta$ using $cos^-1$



    $$theta=cos^-1$$



    I'm stuck on how to determine the appropriate rotation matrix which to rotate about.



    Also, I'm not sure if my process is correct I was looking online to figure this out.







    share|cite|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      What I'm trying to do...



      Say I have two vectors. I want to align these vectors so that they one of my vectors is pointing directly at the other. For example, imagine there is this point and I want to position my camera so that my camera's center is directly aligned with said point.



      From my understanding to do this, I would calculate the cross product between the two vectors and use that as an arbitrary axis of rotation.



      From there I would need an angle $theta,$ which can be determined by taking the dot product between the two vectors and dividing by the product of their magnitudes. Then I would solve for $theta$ using $cos^-1$



      $$theta=cos^-1$$



      I'm stuck on how to determine the appropriate rotation matrix which to rotate about.



      Also, I'm not sure if my process is correct I was looking online to figure this out.







      share|cite|improve this question













      What I'm trying to do...



      Say I have two vectors. I want to align these vectors so that they one of my vectors is pointing directly at the other. For example, imagine there is this point and I want to position my camera so that my camera's center is directly aligned with said point.



      From my understanding to do this, I would calculate the cross product between the two vectors and use that as an arbitrary axis of rotation.



      From there I would need an angle $theta,$ which can be determined by taking the dot product between the two vectors and dividing by the product of their magnitudes. Then I would solve for $theta$ using $cos^-1$



      $$theta=cos^-1$$



      I'm stuck on how to determine the appropriate rotation matrix which to rotate about.



      Also, I'm not sure if my process is correct I was looking online to figure this out.









      share|cite|improve this question












      share|cite|improve this question




      share|cite|improve this question








      edited Jul 26 at 20:07









      saulspatz

      10.4k21323




      10.4k21323









      asked Jul 26 at 20:04









      Markus T.

      31




      31




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          I'm guessing you're intending to program this. So an implementation of @EmilioNovati's reference is illustrated below in C. You give it a rotation axis and a $theta$, and then one function gives you the corresponding quaternion, and then another gives you the $3mboxx3$ rotation matrix corresponding to that quaternion. And a third just conveniently multiplies a vector times a matrix to do the rotation for you. Here's the code, followed by a sample animation using it for rotation calculations...



          /* ---
          * Point and line datatype structs
          * ---------------------------------- */
          #define POINT struct point_struct /* "typedef" for point_struct*/
          #define LINE struct line_struct /* "typedef" for line_struct*/
          #define QUAT struct quaternion_struct /* "typedef" for quaternion_struct */
          POINT double x, y, z; ; /* 3d pts */
          LINE POINT pt1, pt2; ; /* for vectors, pt1=tail, pt2=head */
          QUAT double q0, q1, q2, q3; ; /* quat = q0 + q1*i + q2*j + q3*k */

          /***************************************************************************
          ** +===================================================================+ **
          ** | Low-level quaternion functions, etc | **
          ** +===================================================================+ **
          ***************************************************************************/

          /* ==========================================================================
          * Function: qrotate ( LINE axis, double theta )
          * Purpose: returns quaternion corresponding to rotation
          * through theta (**in radians**) around axis
          * --------------------------------------------------------------------------
          * Arguments: axis (I) LINE axis around which rotation by theta
          * is to occur
          * theta (I) double theta rotation **in radians**
          * --------------------------------------------------------------------------
          * Returns: ( QUAT ) quaternion corresponding to rotation
          * through theta around axis
          * --------------------------------------------------------------------------
          * Notes: o Rotation direction determined by right-hand screw rule
          * (when subsequent qmultiply() is called with istranspose=0)
          * ======================================================================= */
          /* --- entry point --- */
          QUAT qrotate ( LINE axis, double theta )
          /* --- allocations and declarations --- */
          QUAT q = cos(0.5*theta), 0.,0.,0. ; /* constructed quaternion */
          double x = axis.pt2.x - axis.pt1.x, /* length of x-component of axis */
          y = axis.pt2.y - axis.pt1.y, /* length of y-component of axis */
          z = axis.pt2.z - axis.pt1.z; /* length of z-component of axis */
          double r = sqrt((x*x)+(y*y)+(z*z)); /* length of axis */
          double qsin = sin(0.5*theta); /* for q1,q2,q3 components */
          /* --- construct quaternion and return it to caller */
          if ( r >= 0.0000001 ) /* error check */
          q.q1 = qsin*x/r; /* i-component */
          q.q2 = qsin*y/r; /* j-component */
          q.q3 = qsin*z/r; /* k-component */
          return ( q );
          /* --- end-of-function qrotate() --- */


          /* ==========================================================================
          * Function: qmatrix ( QUAT q )
          * Purpose: returns 3x3 rotation matrix corresponding to quaternion q
          * ( can just be called as qmatrix(qrotate(axis,theta))
          * for rotation matrix around axis through theta )
          * --------------------------------------------------------------------------
          * Arguments: q (I) QUAT q for which a rotation matrix
          * is to be constructed
          * --------------------------------------------------------------------------
          * Returns: ( double * ) 3x3 rotation matrix, stored row-wise
          * --------------------------------------------------------------------------
          * Notes: o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
          * (q0 +q1 -q2 -q3 ) 2(q1q2-q0q3) 2(q1q3+q0q2)
          * Q = 2(q2q1+q0q3) (q0 -q1 +q2 -q3 ) 2(q2q3-q0q1)
          * 2(q3q1-q0q2) 2(q3q2+q0q1) (q0 -q1 -q2 +q3 )
          * o The returned matrix is stored row-wise, i.e., explicitly
          * --------- first row ----------
          * qmatrix[0] = (q0 +q1 -q2 -q3 )
          * [1] = 2(q1q2-q0q3)
          * [2] = 2(q1q3+q0q2)
          * --------- second row ---------
          * [3] = 2(q2q1+q0q3)
          * [4] = (q0 -q1 +q2 -q3 )
          * [5] = 2(q2q3-q0q1)
          * --------- third row ----------
          * [6] = 2(q3q1-q0q2)
          * [7] = 2(q3q2+q0q1)
          * [8] = (q0 -q1 -q2 +q3 )
          * o qmatrix maintains a static buffer of 128 3x3 matrices
          * returned to the caller one at a time. So you may issue
          * 128 qmatrix() calls and continue using all returned matrices.
          * The 129th call re-uses the memory used by the 1st call, etc.
          * ======================================================================= */
          /* --- entry point --- */
          double *qmatrix ( QUAT q )
          /* --- allocations and declarations --- */
          static double Qbuff[128][9]; /* up to 128 calls before wrap-around*/
          static int ibuff = (-1); /* Qbuff[ibuff] index 0<=ibuff<=63 */
          double *Q = NULL; /* returned ptr Q=Qbuff[ibuff] */
          double q0=q.q0, q1=q.q1, q2=q.q2, q3=q.q3; /* input quaternion components */
          double q02=q0*q0, q12=q1*q1, q22=q2*q2, q32=q3*q3; /* components squared */
          /* --- first maintain Qbuff[ibuff] buffer --- */
          if ( ++ibuff > 127 ) ibuff=0; /* wrap Qbuff[ibuff] index */
          Q = Qbuff[ibuff]; /* ptr to current 3x3 buffer */
          /* --- just do the algebra described in the above comments --- */
          Q[0] = (q02+q12-q22-q32);
          Q[1] = 2.*(q1*q2-q0*q3);
          Q[2] = 2.*(q1*q3+q0*q2);
          Q[3] = 2.*(q2*q1+q0*q3);
          Q[4] = (q02-q12+q22-q32);
          Q[5] = 2.*(q2*q3-q0*q1);
          Q[6] = 2.*(q3*q1-q0*q2);
          Q[7] = 2.*(q3*q2+q0*q1);
          Q[8] = (q02-q12-q22+q32);
          /* --- return constructed quaternion to caller */
          return ( Q );
          /* --- end-of-function qmatrix() --- */


          /* ==========================================================================
          * Function: qmultiply ( double *Q, POINT u, int istranspose )
          * Purpose: returns Q*u (u a column vector) if istranspose=0,
          * or u*Q (u a row vector) if istranspose=1.
          * --------------------------------------------------------------------------
          * Arguments: Q (I) double *Q to rotation matrix returned
          * by qmatrix (or by some similar construction)
          * u (I) POINT u to column vector (or to row vector
          * if istranspose=1) to be multiplied by Q
          * (or to multiply Q if istranspose=1)
          * istranspose (I) int istranspose=0 to return Q*u (u a col vec),
          * or istranspose=1 to return u*q (u a row vec)
          * --------------------------------------------------------------------------
          * Returns: ( POINT ) Q*u (istranspose=0), or u*Q (istranspose=1)
          * --------------------------------------------------------------------------
          * Notes: o Q assumed to be a 3x3 matrix stored row-wise
          * ======================================================================= */
          /* --- entry point --- */
          POINT qmultiply ( double *Q, POINT u, int istranspose )
          /* --- allocations and declarations --- */
          POINT Qu = 0.,0.,0. ; /* Q*u (or u*Q if istranspose=1) */
          double x=u.x, y=u.y, z=u.z; /* x(i),y(j),z(k)-components of u */
          /* --- Q*u --- */
          if ( !istranspose )
          Qu.x = Q[0]*x + Q[1]*y + Q[2]*z; /* first row of Q * column vector u */
          Qu.y = Q[3]*x + Q[4]*y + Q[5]*z; /* second row of Q * column vector u */
          Qu.z = Q[6]*x + Q[7]*y + Q[8]*z; /* third row of Q * column vector u */
          /* --- end-of-if(!istranspose) --- */
          /* --- u*Q --- */
          if ( istranspose )
          Qu.x = x*Q[0] + y*Q[3] + z*Q[6]; /* row vector u * first column of Q */
          Qu.y = x*Q[1] + y*Q[4] + z*Q[7]; /* row vector u * second column of Q */
          Qu.z = x*Q[2] + y*Q[5] + z*Q[8]; /* row vector u * third column of Q */
          /* --- end-of-if(istranspose) --- */
          /* --- return product to caller --- */
          return ( Qu );
          /* --- end-of-function qmultiply() --- */


          And here's a sample animation that uses the above functions to perform the frame-by-frame rotations...
          enter image description here






          share|cite|improve this answer





















          • Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
            – Markus T.
            Jul 26 at 21:53










          • @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
            – John Forkosh
            Jul 26 at 22:40










          • I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
            – Markus T.
            Jul 26 at 23:16










          • @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
            – John Forkosh
            Jul 27 at 8:46

















          up vote
          0
          down vote













          Yes, the rotation axis is oriented by the vector orthogonal to the two vectors, but we have to use a normalized vector $$vec u=fracvec a times vec bvec b$$, and the angle $theta$ of rotation is obtained from the inner product of the two vectors as you have done.



          The matrix that represents the rotation around the axis $vec u$ of angle $theta$ is given here.






          share|cite|improve this answer




























            up vote
            0
            down vote













            If you look at
            https://wikimedia.org/api/rest_v1/media/math/render/svg/f259f80a746ee20d481f9b7f600031084358a27c
            formula from wikipedia(I don't have enough rep to include the image)



            we obtain the general formula for a rotation matrix about an axis defined by the vector $(u_x,u_y,u_z)$. As you said, we obtain the angle between two vectors $v$ and $w$ with $fracvcdot wv$ and plug that in for theta. Then we take $vtimes w$ to be the vector $u$.






            share|cite|improve this answer





















              Your Answer




              StackExchange.ifUsing("editor", function ()
              return StackExchange.using("mathjaxEditing", function ()
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
              );
              );
              , "mathjax-editing");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "69"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              noCode: true, onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2863768%2fhow-to-rotate-a-vector-about-an-arbitrary-axis-in-3d-to-align-two-vectors%23new-answer', 'question_page');

              );

              Post as a guest






























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              0
              down vote



              accepted










              I'm guessing you're intending to program this. So an implementation of @EmilioNovati's reference is illustrated below in C. You give it a rotation axis and a $theta$, and then one function gives you the corresponding quaternion, and then another gives you the $3mboxx3$ rotation matrix corresponding to that quaternion. And a third just conveniently multiplies a vector times a matrix to do the rotation for you. Here's the code, followed by a sample animation using it for rotation calculations...



              /* ---
              * Point and line datatype structs
              * ---------------------------------- */
              #define POINT struct point_struct /* "typedef" for point_struct*/
              #define LINE struct line_struct /* "typedef" for line_struct*/
              #define QUAT struct quaternion_struct /* "typedef" for quaternion_struct */
              POINT double x, y, z; ; /* 3d pts */
              LINE POINT pt1, pt2; ; /* for vectors, pt1=tail, pt2=head */
              QUAT double q0, q1, q2, q3; ; /* quat = q0 + q1*i + q2*j + q3*k */

              /***************************************************************************
              ** +===================================================================+ **
              ** | Low-level quaternion functions, etc | **
              ** +===================================================================+ **
              ***************************************************************************/

              /* ==========================================================================
              * Function: qrotate ( LINE axis, double theta )
              * Purpose: returns quaternion corresponding to rotation
              * through theta (**in radians**) around axis
              * --------------------------------------------------------------------------
              * Arguments: axis (I) LINE axis around which rotation by theta
              * is to occur
              * theta (I) double theta rotation **in radians**
              * --------------------------------------------------------------------------
              * Returns: ( QUAT ) quaternion corresponding to rotation
              * through theta around axis
              * --------------------------------------------------------------------------
              * Notes: o Rotation direction determined by right-hand screw rule
              * (when subsequent qmultiply() is called with istranspose=0)
              * ======================================================================= */
              /* --- entry point --- */
              QUAT qrotate ( LINE axis, double theta )
              /* --- allocations and declarations --- */
              QUAT q = cos(0.5*theta), 0.,0.,0. ; /* constructed quaternion */
              double x = axis.pt2.x - axis.pt1.x, /* length of x-component of axis */
              y = axis.pt2.y - axis.pt1.y, /* length of y-component of axis */
              z = axis.pt2.z - axis.pt1.z; /* length of z-component of axis */
              double r = sqrt((x*x)+(y*y)+(z*z)); /* length of axis */
              double qsin = sin(0.5*theta); /* for q1,q2,q3 components */
              /* --- construct quaternion and return it to caller */
              if ( r >= 0.0000001 ) /* error check */
              q.q1 = qsin*x/r; /* i-component */
              q.q2 = qsin*y/r; /* j-component */
              q.q3 = qsin*z/r; /* k-component */
              return ( q );
              /* --- end-of-function qrotate() --- */


              /* ==========================================================================
              * Function: qmatrix ( QUAT q )
              * Purpose: returns 3x3 rotation matrix corresponding to quaternion q
              * ( can just be called as qmatrix(qrotate(axis,theta))
              * for rotation matrix around axis through theta )
              * --------------------------------------------------------------------------
              * Arguments: q (I) QUAT q for which a rotation matrix
              * is to be constructed
              * --------------------------------------------------------------------------
              * Returns: ( double * ) 3x3 rotation matrix, stored row-wise
              * --------------------------------------------------------------------------
              * Notes: o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
              * (q0 +q1 -q2 -q3 ) 2(q1q2-q0q3) 2(q1q3+q0q2)
              * Q = 2(q2q1+q0q3) (q0 -q1 +q2 -q3 ) 2(q2q3-q0q1)
              * 2(q3q1-q0q2) 2(q3q2+q0q1) (q0 -q1 -q2 +q3 )
              * o The returned matrix is stored row-wise, i.e., explicitly
              * --------- first row ----------
              * qmatrix[0] = (q0 +q1 -q2 -q3 )
              * [1] = 2(q1q2-q0q3)
              * [2] = 2(q1q3+q0q2)
              * --------- second row ---------
              * [3] = 2(q2q1+q0q3)
              * [4] = (q0 -q1 +q2 -q3 )
              * [5] = 2(q2q3-q0q1)
              * --------- third row ----------
              * [6] = 2(q3q1-q0q2)
              * [7] = 2(q3q2+q0q1)
              * [8] = (q0 -q1 -q2 +q3 )
              * o qmatrix maintains a static buffer of 128 3x3 matrices
              * returned to the caller one at a time. So you may issue
              * 128 qmatrix() calls and continue using all returned matrices.
              * The 129th call re-uses the memory used by the 1st call, etc.
              * ======================================================================= */
              /* --- entry point --- */
              double *qmatrix ( QUAT q )
              /* --- allocations and declarations --- */
              static double Qbuff[128][9]; /* up to 128 calls before wrap-around*/
              static int ibuff = (-1); /* Qbuff[ibuff] index 0<=ibuff<=63 */
              double *Q = NULL; /* returned ptr Q=Qbuff[ibuff] */
              double q0=q.q0, q1=q.q1, q2=q.q2, q3=q.q3; /* input quaternion components */
              double q02=q0*q0, q12=q1*q1, q22=q2*q2, q32=q3*q3; /* components squared */
              /* --- first maintain Qbuff[ibuff] buffer --- */
              if ( ++ibuff > 127 ) ibuff=0; /* wrap Qbuff[ibuff] index */
              Q = Qbuff[ibuff]; /* ptr to current 3x3 buffer */
              /* --- just do the algebra described in the above comments --- */
              Q[0] = (q02+q12-q22-q32);
              Q[1] = 2.*(q1*q2-q0*q3);
              Q[2] = 2.*(q1*q3+q0*q2);
              Q[3] = 2.*(q2*q1+q0*q3);
              Q[4] = (q02-q12+q22-q32);
              Q[5] = 2.*(q2*q3-q0*q1);
              Q[6] = 2.*(q3*q1-q0*q2);
              Q[7] = 2.*(q3*q2+q0*q1);
              Q[8] = (q02-q12-q22+q32);
              /* --- return constructed quaternion to caller */
              return ( Q );
              /* --- end-of-function qmatrix() --- */


              /* ==========================================================================
              * Function: qmultiply ( double *Q, POINT u, int istranspose )
              * Purpose: returns Q*u (u a column vector) if istranspose=0,
              * or u*Q (u a row vector) if istranspose=1.
              * --------------------------------------------------------------------------
              * Arguments: Q (I) double *Q to rotation matrix returned
              * by qmatrix (or by some similar construction)
              * u (I) POINT u to column vector (or to row vector
              * if istranspose=1) to be multiplied by Q
              * (or to multiply Q if istranspose=1)
              * istranspose (I) int istranspose=0 to return Q*u (u a col vec),
              * or istranspose=1 to return u*q (u a row vec)
              * --------------------------------------------------------------------------
              * Returns: ( POINT ) Q*u (istranspose=0), or u*Q (istranspose=1)
              * --------------------------------------------------------------------------
              * Notes: o Q assumed to be a 3x3 matrix stored row-wise
              * ======================================================================= */
              /* --- entry point --- */
              POINT qmultiply ( double *Q, POINT u, int istranspose )
              /* --- allocations and declarations --- */
              POINT Qu = 0.,0.,0. ; /* Q*u (or u*Q if istranspose=1) */
              double x=u.x, y=u.y, z=u.z; /* x(i),y(j),z(k)-components of u */
              /* --- Q*u --- */
              if ( !istranspose )
              Qu.x = Q[0]*x + Q[1]*y + Q[2]*z; /* first row of Q * column vector u */
              Qu.y = Q[3]*x + Q[4]*y + Q[5]*z; /* second row of Q * column vector u */
              Qu.z = Q[6]*x + Q[7]*y + Q[8]*z; /* third row of Q * column vector u */
              /* --- end-of-if(!istranspose) --- */
              /* --- u*Q --- */
              if ( istranspose )
              Qu.x = x*Q[0] + y*Q[3] + z*Q[6]; /* row vector u * first column of Q */
              Qu.y = x*Q[1] + y*Q[4] + z*Q[7]; /* row vector u * second column of Q */
              Qu.z = x*Q[2] + y*Q[5] + z*Q[8]; /* row vector u * third column of Q */
              /* --- end-of-if(istranspose) --- */
              /* --- return product to caller --- */
              return ( Qu );
              /* --- end-of-function qmultiply() --- */


              And here's a sample animation that uses the above functions to perform the frame-by-frame rotations...
              enter image description here






              share|cite|improve this answer





















              • Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
                – Markus T.
                Jul 26 at 21:53










              • @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
                – John Forkosh
                Jul 26 at 22:40










              • I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
                – Markus T.
                Jul 26 at 23:16










              • @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
                – John Forkosh
                Jul 27 at 8:46














              up vote
              0
              down vote



              accepted










              I'm guessing you're intending to program this. So an implementation of @EmilioNovati's reference is illustrated below in C. You give it a rotation axis and a $theta$, and then one function gives you the corresponding quaternion, and then another gives you the $3mboxx3$ rotation matrix corresponding to that quaternion. And a third just conveniently multiplies a vector times a matrix to do the rotation for you. Here's the code, followed by a sample animation using it for rotation calculations...



              /* ---
              * Point and line datatype structs
              * ---------------------------------- */
              #define POINT struct point_struct /* "typedef" for point_struct*/
              #define LINE struct line_struct /* "typedef" for line_struct*/
              #define QUAT struct quaternion_struct /* "typedef" for quaternion_struct */
              POINT double x, y, z; ; /* 3d pts */
              LINE POINT pt1, pt2; ; /* for vectors, pt1=tail, pt2=head */
              QUAT double q0, q1, q2, q3; ; /* quat = q0 + q1*i + q2*j + q3*k */

              /***************************************************************************
              ** +===================================================================+ **
              ** | Low-level quaternion functions, etc | **
              ** +===================================================================+ **
              ***************************************************************************/

              /* ==========================================================================
              * Function: qrotate ( LINE axis, double theta )
              * Purpose: returns quaternion corresponding to rotation
              * through theta (**in radians**) around axis
              * --------------------------------------------------------------------------
              * Arguments: axis (I) LINE axis around which rotation by theta
              * is to occur
              * theta (I) double theta rotation **in radians**
              * --------------------------------------------------------------------------
              * Returns: ( QUAT ) quaternion corresponding to rotation
              * through theta around axis
              * --------------------------------------------------------------------------
              * Notes: o Rotation direction determined by right-hand screw rule
              * (when subsequent qmultiply() is called with istranspose=0)
              * ======================================================================= */
              /* --- entry point --- */
              QUAT qrotate ( LINE axis, double theta )
              /* --- allocations and declarations --- */
              QUAT q = cos(0.5*theta), 0.,0.,0. ; /* constructed quaternion */
              double x = axis.pt2.x - axis.pt1.x, /* length of x-component of axis */
              y = axis.pt2.y - axis.pt1.y, /* length of y-component of axis */
              z = axis.pt2.z - axis.pt1.z; /* length of z-component of axis */
              double r = sqrt((x*x)+(y*y)+(z*z)); /* length of axis */
              double qsin = sin(0.5*theta); /* for q1,q2,q3 components */
              /* --- construct quaternion and return it to caller */
              if ( r >= 0.0000001 ) /* error check */
              q.q1 = qsin*x/r; /* i-component */
              q.q2 = qsin*y/r; /* j-component */
              q.q3 = qsin*z/r; /* k-component */
              return ( q );
              /* --- end-of-function qrotate() --- */


              /* ==========================================================================
              * Function: qmatrix ( QUAT q )
              * Purpose: returns 3x3 rotation matrix corresponding to quaternion q
              * ( can just be called as qmatrix(qrotate(axis,theta))
              * for rotation matrix around axis through theta )
              * --------------------------------------------------------------------------
              * Arguments: q (I) QUAT q for which a rotation matrix
              * is to be constructed
              * --------------------------------------------------------------------------
              * Returns: ( double * ) 3x3 rotation matrix, stored row-wise
              * --------------------------------------------------------------------------
              * Notes: o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
              * (q0 +q1 -q2 -q3 ) 2(q1q2-q0q3) 2(q1q3+q0q2)
              * Q = 2(q2q1+q0q3) (q0 -q1 +q2 -q3 ) 2(q2q3-q0q1)
              * 2(q3q1-q0q2) 2(q3q2+q0q1) (q0 -q1 -q2 +q3 )
              * o The returned matrix is stored row-wise, i.e., explicitly
              * --------- first row ----------
              * qmatrix[0] = (q0 +q1 -q2 -q3 )
              * [1] = 2(q1q2-q0q3)
              * [2] = 2(q1q3+q0q2)
              * --------- second row ---------
              * [3] = 2(q2q1+q0q3)
              * [4] = (q0 -q1 +q2 -q3 )
              * [5] = 2(q2q3-q0q1)
              * --------- third row ----------
              * [6] = 2(q3q1-q0q2)
              * [7] = 2(q3q2+q0q1)
              * [8] = (q0 -q1 -q2 +q3 )
              * o qmatrix maintains a static buffer of 128 3x3 matrices
              * returned to the caller one at a time. So you may issue
              * 128 qmatrix() calls and continue using all returned matrices.
              * The 129th call re-uses the memory used by the 1st call, etc.
              * ======================================================================= */
              /* --- entry point --- */
              double *qmatrix ( QUAT q )
              /* --- allocations and declarations --- */
              static double Qbuff[128][9]; /* up to 128 calls before wrap-around*/
              static int ibuff = (-1); /* Qbuff[ibuff] index 0<=ibuff<=63 */
              double *Q = NULL; /* returned ptr Q=Qbuff[ibuff] */
              double q0=q.q0, q1=q.q1, q2=q.q2, q3=q.q3; /* input quaternion components */
              double q02=q0*q0, q12=q1*q1, q22=q2*q2, q32=q3*q3; /* components squared */
              /* --- first maintain Qbuff[ibuff] buffer --- */
              if ( ++ibuff > 127 ) ibuff=0; /* wrap Qbuff[ibuff] index */
              Q = Qbuff[ibuff]; /* ptr to current 3x3 buffer */
              /* --- just do the algebra described in the above comments --- */
              Q[0] = (q02+q12-q22-q32);
              Q[1] = 2.*(q1*q2-q0*q3);
              Q[2] = 2.*(q1*q3+q0*q2);
              Q[3] = 2.*(q2*q1+q0*q3);
              Q[4] = (q02-q12+q22-q32);
              Q[5] = 2.*(q2*q3-q0*q1);
              Q[6] = 2.*(q3*q1-q0*q2);
              Q[7] = 2.*(q3*q2+q0*q1);
              Q[8] = (q02-q12-q22+q32);
              /* --- return constructed quaternion to caller */
              return ( Q );
              /* --- end-of-function qmatrix() --- */


              /* ==========================================================================
              * Function: qmultiply ( double *Q, POINT u, int istranspose )
              * Purpose: returns Q*u (u a column vector) if istranspose=0,
              * or u*Q (u a row vector) if istranspose=1.
              * --------------------------------------------------------------------------
              * Arguments: Q (I) double *Q to rotation matrix returned
              * by qmatrix (or by some similar construction)
              * u (I) POINT u to column vector (or to row vector
              * if istranspose=1) to be multiplied by Q
              * (or to multiply Q if istranspose=1)
              * istranspose (I) int istranspose=0 to return Q*u (u a col vec),
              * or istranspose=1 to return u*q (u a row vec)
              * --------------------------------------------------------------------------
              * Returns: ( POINT ) Q*u (istranspose=0), or u*Q (istranspose=1)
              * --------------------------------------------------------------------------
              * Notes: o Q assumed to be a 3x3 matrix stored row-wise
              * ======================================================================= */
              /* --- entry point --- */
              POINT qmultiply ( double *Q, POINT u, int istranspose )
              /* --- allocations and declarations --- */
              POINT Qu = 0.,0.,0. ; /* Q*u (or u*Q if istranspose=1) */
              double x=u.x, y=u.y, z=u.z; /* x(i),y(j),z(k)-components of u */
              /* --- Q*u --- */
              if ( !istranspose )
              Qu.x = Q[0]*x + Q[1]*y + Q[2]*z; /* first row of Q * column vector u */
              Qu.y = Q[3]*x + Q[4]*y + Q[5]*z; /* second row of Q * column vector u */
              Qu.z = Q[6]*x + Q[7]*y + Q[8]*z; /* third row of Q * column vector u */
              /* --- end-of-if(!istranspose) --- */
              /* --- u*Q --- */
              if ( istranspose )
              Qu.x = x*Q[0] + y*Q[3] + z*Q[6]; /* row vector u * first column of Q */
              Qu.y = x*Q[1] + y*Q[4] + z*Q[7]; /* row vector u * second column of Q */
              Qu.z = x*Q[2] + y*Q[5] + z*Q[8]; /* row vector u * third column of Q */
              /* --- end-of-if(istranspose) --- */
              /* --- return product to caller --- */
              return ( Qu );
              /* --- end-of-function qmultiply() --- */


              And here's a sample animation that uses the above functions to perform the frame-by-frame rotations...
              enter image description here






              share|cite|improve this answer





















              • Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
                – Markus T.
                Jul 26 at 21:53










              • @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
                – John Forkosh
                Jul 26 at 22:40










              • I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
                – Markus T.
                Jul 26 at 23:16










              • @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
                – John Forkosh
                Jul 27 at 8:46












              up vote
              0
              down vote



              accepted







              up vote
              0
              down vote



              accepted






              I'm guessing you're intending to program this. So an implementation of @EmilioNovati's reference is illustrated below in C. You give it a rotation axis and a $theta$, and then one function gives you the corresponding quaternion, and then another gives you the $3mboxx3$ rotation matrix corresponding to that quaternion. And a third just conveniently multiplies a vector times a matrix to do the rotation for you. Here's the code, followed by a sample animation using it for rotation calculations...



              /* ---
              * Point and line datatype structs
              * ---------------------------------- */
              #define POINT struct point_struct /* "typedef" for point_struct*/
              #define LINE struct line_struct /* "typedef" for line_struct*/
              #define QUAT struct quaternion_struct /* "typedef" for quaternion_struct */
              POINT double x, y, z; ; /* 3d pts */
              LINE POINT pt1, pt2; ; /* for vectors, pt1=tail, pt2=head */
              QUAT double q0, q1, q2, q3; ; /* quat = q0 + q1*i + q2*j + q3*k */

              /***************************************************************************
              ** +===================================================================+ **
              ** | Low-level quaternion functions, etc | **
              ** +===================================================================+ **
              ***************************************************************************/

              /* ==========================================================================
              * Function: qrotate ( LINE axis, double theta )
              * Purpose: returns quaternion corresponding to rotation
              * through theta (**in radians**) around axis
              * --------------------------------------------------------------------------
              * Arguments: axis (I) LINE axis around which rotation by theta
              * is to occur
              * theta (I) double theta rotation **in radians**
              * --------------------------------------------------------------------------
              * Returns: ( QUAT ) quaternion corresponding to rotation
              * through theta around axis
              * --------------------------------------------------------------------------
              * Notes: o Rotation direction determined by right-hand screw rule
              * (when subsequent qmultiply() is called with istranspose=0)
              * ======================================================================= */
              /* --- entry point --- */
              QUAT qrotate ( LINE axis, double theta )
              /* --- allocations and declarations --- */
              QUAT q = cos(0.5*theta), 0.,0.,0. ; /* constructed quaternion */
              double x = axis.pt2.x - axis.pt1.x, /* length of x-component of axis */
              y = axis.pt2.y - axis.pt1.y, /* length of y-component of axis */
              z = axis.pt2.z - axis.pt1.z; /* length of z-component of axis */
              double r = sqrt((x*x)+(y*y)+(z*z)); /* length of axis */
              double qsin = sin(0.5*theta); /* for q1,q2,q3 components */
              /* --- construct quaternion and return it to caller */
              if ( r >= 0.0000001 ) /* error check */
              q.q1 = qsin*x/r; /* i-component */
              q.q2 = qsin*y/r; /* j-component */
              q.q3 = qsin*z/r; /* k-component */
              return ( q );
              /* --- end-of-function qrotate() --- */


              /* ==========================================================================
              * Function: qmatrix ( QUAT q )
              * Purpose: returns 3x3 rotation matrix corresponding to quaternion q
              * ( can just be called as qmatrix(qrotate(axis,theta))
              * for rotation matrix around axis through theta )
              * --------------------------------------------------------------------------
              * Arguments: q (I) QUAT q for which a rotation matrix
              * is to be constructed
              * --------------------------------------------------------------------------
              * Returns: ( double * ) 3x3 rotation matrix, stored row-wise
              * --------------------------------------------------------------------------
              * Notes: o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
              * (q0 +q1 -q2 -q3 ) 2(q1q2-q0q3) 2(q1q3+q0q2)
              * Q = 2(q2q1+q0q3) (q0 -q1 +q2 -q3 ) 2(q2q3-q0q1)
              * 2(q3q1-q0q2) 2(q3q2+q0q1) (q0 -q1 -q2 +q3 )
              * o The returned matrix is stored row-wise, i.e., explicitly
              * --------- first row ----------
              * qmatrix[0] = (q0 +q1 -q2 -q3 )
              * [1] = 2(q1q2-q0q3)
              * [2] = 2(q1q3+q0q2)
              * --------- second row ---------
              * [3] = 2(q2q1+q0q3)
              * [4] = (q0 -q1 +q2 -q3 )
              * [5] = 2(q2q3-q0q1)
              * --------- third row ----------
              * [6] = 2(q3q1-q0q2)
              * [7] = 2(q3q2+q0q1)
              * [8] = (q0 -q1 -q2 +q3 )
              * o qmatrix maintains a static buffer of 128 3x3 matrices
              * returned to the caller one at a time. So you may issue
              * 128 qmatrix() calls and continue using all returned matrices.
              * The 129th call re-uses the memory used by the 1st call, etc.
              * ======================================================================= */
              /* --- entry point --- */
              double *qmatrix ( QUAT q )
              /* --- allocations and declarations --- */
              static double Qbuff[128][9]; /* up to 128 calls before wrap-around*/
              static int ibuff = (-1); /* Qbuff[ibuff] index 0<=ibuff<=63 */
              double *Q = NULL; /* returned ptr Q=Qbuff[ibuff] */
              double q0=q.q0, q1=q.q1, q2=q.q2, q3=q.q3; /* input quaternion components */
              double q02=q0*q0, q12=q1*q1, q22=q2*q2, q32=q3*q3; /* components squared */
              /* --- first maintain Qbuff[ibuff] buffer --- */
              if ( ++ibuff > 127 ) ibuff=0; /* wrap Qbuff[ibuff] index */
              Q = Qbuff[ibuff]; /* ptr to current 3x3 buffer */
              /* --- just do the algebra described in the above comments --- */
              Q[0] = (q02+q12-q22-q32);
              Q[1] = 2.*(q1*q2-q0*q3);
              Q[2] = 2.*(q1*q3+q0*q2);
              Q[3] = 2.*(q2*q1+q0*q3);
              Q[4] = (q02-q12+q22-q32);
              Q[5] = 2.*(q2*q3-q0*q1);
              Q[6] = 2.*(q3*q1-q0*q2);
              Q[7] = 2.*(q3*q2+q0*q1);
              Q[8] = (q02-q12-q22+q32);
              /* --- return constructed quaternion to caller */
              return ( Q );
              /* --- end-of-function qmatrix() --- */


              /* ==========================================================================
              * Function: qmultiply ( double *Q, POINT u, int istranspose )
              * Purpose: returns Q*u (u a column vector) if istranspose=0,
              * or u*Q (u a row vector) if istranspose=1.
              * --------------------------------------------------------------------------
              * Arguments: Q (I) double *Q to rotation matrix returned
              * by qmatrix (or by some similar construction)
              * u (I) POINT u to column vector (or to row vector
              * if istranspose=1) to be multiplied by Q
              * (or to multiply Q if istranspose=1)
              * istranspose (I) int istranspose=0 to return Q*u (u a col vec),
              * or istranspose=1 to return u*q (u a row vec)
              * --------------------------------------------------------------------------
              * Returns: ( POINT ) Q*u (istranspose=0), or u*Q (istranspose=1)
              * --------------------------------------------------------------------------
              * Notes: o Q assumed to be a 3x3 matrix stored row-wise
              * ======================================================================= */
              /* --- entry point --- */
              POINT qmultiply ( double *Q, POINT u, int istranspose )
              /* --- allocations and declarations --- */
              POINT Qu = 0.,0.,0. ; /* Q*u (or u*Q if istranspose=1) */
              double x=u.x, y=u.y, z=u.z; /* x(i),y(j),z(k)-components of u */
              /* --- Q*u --- */
              if ( !istranspose )
              Qu.x = Q[0]*x + Q[1]*y + Q[2]*z; /* first row of Q * column vector u */
              Qu.y = Q[3]*x + Q[4]*y + Q[5]*z; /* second row of Q * column vector u */
              Qu.z = Q[6]*x + Q[7]*y + Q[8]*z; /* third row of Q * column vector u */
              /* --- end-of-if(!istranspose) --- */
              /* --- u*Q --- */
              if ( istranspose )
              Qu.x = x*Q[0] + y*Q[3] + z*Q[6]; /* row vector u * first column of Q */
              Qu.y = x*Q[1] + y*Q[4] + z*Q[7]; /* row vector u * second column of Q */
              Qu.z = x*Q[2] + y*Q[5] + z*Q[8]; /* row vector u * third column of Q */
              /* --- end-of-if(istranspose) --- */
              /* --- return product to caller --- */
              return ( Qu );
              /* --- end-of-function qmultiply() --- */


              And here's a sample animation that uses the above functions to perform the frame-by-frame rotations...
              enter image description here






              share|cite|improve this answer













              I'm guessing you're intending to program this. So an implementation of @EmilioNovati's reference is illustrated below in C. You give it a rotation axis and a $theta$, and then one function gives you the corresponding quaternion, and then another gives you the $3mboxx3$ rotation matrix corresponding to that quaternion. And a third just conveniently multiplies a vector times a matrix to do the rotation for you. Here's the code, followed by a sample animation using it for rotation calculations...



              /* ---
              * Point and line datatype structs
              * ---------------------------------- */
              #define POINT struct point_struct /* "typedef" for point_struct*/
              #define LINE struct line_struct /* "typedef" for line_struct*/
              #define QUAT struct quaternion_struct /* "typedef" for quaternion_struct */
              POINT double x, y, z; ; /* 3d pts */
              LINE POINT pt1, pt2; ; /* for vectors, pt1=tail, pt2=head */
              QUAT double q0, q1, q2, q3; ; /* quat = q0 + q1*i + q2*j + q3*k */

              /***************************************************************************
              ** +===================================================================+ **
              ** | Low-level quaternion functions, etc | **
              ** +===================================================================+ **
              ***************************************************************************/

              /* ==========================================================================
              * Function: qrotate ( LINE axis, double theta )
              * Purpose: returns quaternion corresponding to rotation
              * through theta (**in radians**) around axis
              * --------------------------------------------------------------------------
              * Arguments: axis (I) LINE axis around which rotation by theta
              * is to occur
              * theta (I) double theta rotation **in radians**
              * --------------------------------------------------------------------------
              * Returns: ( QUAT ) quaternion corresponding to rotation
              * through theta around axis
              * --------------------------------------------------------------------------
              * Notes: o Rotation direction determined by right-hand screw rule
              * (when subsequent qmultiply() is called with istranspose=0)
              * ======================================================================= */
              /* --- entry point --- */
              QUAT qrotate ( LINE axis, double theta )
              /* --- allocations and declarations --- */
              QUAT q = cos(0.5*theta), 0.,0.,0. ; /* constructed quaternion */
              double x = axis.pt2.x - axis.pt1.x, /* length of x-component of axis */
              y = axis.pt2.y - axis.pt1.y, /* length of y-component of axis */
              z = axis.pt2.z - axis.pt1.z; /* length of z-component of axis */
              double r = sqrt((x*x)+(y*y)+(z*z)); /* length of axis */
              double qsin = sin(0.5*theta); /* for q1,q2,q3 components */
              /* --- construct quaternion and return it to caller */
              if ( r >= 0.0000001 ) /* error check */
              q.q1 = qsin*x/r; /* i-component */
              q.q2 = qsin*y/r; /* j-component */
              q.q3 = qsin*z/r; /* k-component */
              return ( q );
              /* --- end-of-function qrotate() --- */


              /* ==========================================================================
              * Function: qmatrix ( QUAT q )
              * Purpose: returns 3x3 rotation matrix corresponding to quaternion q
              * ( can just be called as qmatrix(qrotate(axis,theta))
              * for rotation matrix around axis through theta )
              * --------------------------------------------------------------------------
              * Arguments: q (I) QUAT q for which a rotation matrix
              * is to be constructed
              * --------------------------------------------------------------------------
              * Returns: ( double * ) 3x3 rotation matrix, stored row-wise
              * --------------------------------------------------------------------------
              * Notes: o The matrix constructed from input q = q0+q1*i+q2*j+q3*k is:
              * (q0 +q1 -q2 -q3 ) 2(q1q2-q0q3) 2(q1q3+q0q2)
              * Q = 2(q2q1+q0q3) (q0 -q1 +q2 -q3 ) 2(q2q3-q0q1)
              * 2(q3q1-q0q2) 2(q3q2+q0q1) (q0 -q1 -q2 +q3 )
              * o The returned matrix is stored row-wise, i.e., explicitly
              * --------- first row ----------
              * qmatrix[0] = (q0 +q1 -q2 -q3 )
              * [1] = 2(q1q2-q0q3)
              * [2] = 2(q1q3+q0q2)
              * --------- second row ---------
              * [3] = 2(q2q1+q0q3)
              * [4] = (q0 -q1 +q2 -q3 )
              * [5] = 2(q2q3-q0q1)
              * --------- third row ----------
              * [6] = 2(q3q1-q0q2)
              * [7] = 2(q3q2+q0q1)
              * [8] = (q0 -q1 -q2 +q3 )
              * o qmatrix maintains a static buffer of 128 3x3 matrices
              * returned to the caller one at a time. So you may issue
              * 128 qmatrix() calls and continue using all returned matrices.
              * The 129th call re-uses the memory used by the 1st call, etc.
              * ======================================================================= */
              /* --- entry point --- */
              double *qmatrix ( QUAT q )
              /* --- allocations and declarations --- */
              static double Qbuff[128][9]; /* up to 128 calls before wrap-around*/
              static int ibuff = (-1); /* Qbuff[ibuff] index 0<=ibuff<=63 */
              double *Q = NULL; /* returned ptr Q=Qbuff[ibuff] */
              double q0=q.q0, q1=q.q1, q2=q.q2, q3=q.q3; /* input quaternion components */
              double q02=q0*q0, q12=q1*q1, q22=q2*q2, q32=q3*q3; /* components squared */
              /* --- first maintain Qbuff[ibuff] buffer --- */
              if ( ++ibuff > 127 ) ibuff=0; /* wrap Qbuff[ibuff] index */
              Q = Qbuff[ibuff]; /* ptr to current 3x3 buffer */
              /* --- just do the algebra described in the above comments --- */
              Q[0] = (q02+q12-q22-q32);
              Q[1] = 2.*(q1*q2-q0*q3);
              Q[2] = 2.*(q1*q3+q0*q2);
              Q[3] = 2.*(q2*q1+q0*q3);
              Q[4] = (q02-q12+q22-q32);
              Q[5] = 2.*(q2*q3-q0*q1);
              Q[6] = 2.*(q3*q1-q0*q2);
              Q[7] = 2.*(q3*q2+q0*q1);
              Q[8] = (q02-q12-q22+q32);
              /* --- return constructed quaternion to caller */
              return ( Q );
              /* --- end-of-function qmatrix() --- */


              /* ==========================================================================
              * Function: qmultiply ( double *Q, POINT u, int istranspose )
              * Purpose: returns Q*u (u a column vector) if istranspose=0,
              * or u*Q (u a row vector) if istranspose=1.
              * --------------------------------------------------------------------------
              * Arguments: Q (I) double *Q to rotation matrix returned
              * by qmatrix (or by some similar construction)
              * u (I) POINT u to column vector (or to row vector
              * if istranspose=1) to be multiplied by Q
              * (or to multiply Q if istranspose=1)
              * istranspose (I) int istranspose=0 to return Q*u (u a col vec),
              * or istranspose=1 to return u*q (u a row vec)
              * --------------------------------------------------------------------------
              * Returns: ( POINT ) Q*u (istranspose=0), or u*Q (istranspose=1)
              * --------------------------------------------------------------------------
              * Notes: o Q assumed to be a 3x3 matrix stored row-wise
              * ======================================================================= */
              /* --- entry point --- */
              POINT qmultiply ( double *Q, POINT u, int istranspose )
              /* --- allocations and declarations --- */
              POINT Qu = 0.,0.,0. ; /* Q*u (or u*Q if istranspose=1) */
              double x=u.x, y=u.y, z=u.z; /* x(i),y(j),z(k)-components of u */
              /* --- Q*u --- */
              if ( !istranspose )
              Qu.x = Q[0]*x + Q[1]*y + Q[2]*z; /* first row of Q * column vector u */
              Qu.y = Q[3]*x + Q[4]*y + Q[5]*z; /* second row of Q * column vector u */
              Qu.z = Q[6]*x + Q[7]*y + Q[8]*z; /* third row of Q * column vector u */
              /* --- end-of-if(!istranspose) --- */
              /* --- u*Q --- */
              if ( istranspose )
              Qu.x = x*Q[0] + y*Q[3] + z*Q[6]; /* row vector u * first column of Q */
              Qu.y = x*Q[1] + y*Q[4] + z*Q[7]; /* row vector u * second column of Q */
              Qu.z = x*Q[2] + y*Q[5] + z*Q[8]; /* row vector u * third column of Q */
              /* --- end-of-if(istranspose) --- */
              /* --- return product to caller --- */
              return ( Qu );
              /* --- end-of-function qmultiply() --- */


              And here's a sample animation that uses the above functions to perform the frame-by-frame rotations...
              enter image description here







              share|cite|improve this answer













              share|cite|improve this answer



              share|cite|improve this answer











              answered Jul 26 at 20:48









              John Forkosh

              304110




              304110











              • Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
                – Markus T.
                Jul 26 at 21:53










              • @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
                – John Forkosh
                Jul 26 at 22:40










              • I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
                – Markus T.
                Jul 26 at 23:16










              • @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
                – John Forkosh
                Jul 27 at 8:46
















              • Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
                – Markus T.
                Jul 26 at 21:53










              • @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
                – John Forkosh
                Jul 26 at 22:40










              • I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
                – Markus T.
                Jul 26 at 23:16










              • @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
                – John Forkosh
                Jul 27 at 8:46















              Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
              – Markus T.
              Jul 26 at 21:53




              Thanks for the explanation! My mathematical background isn't enough to understand this completely, but it is a good jump off point for me to learn from. If this works with what I'm doing I will mark it as correct!
              – Markus T.
              Jul 26 at 21:53












              @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
              – John Forkosh
              Jul 26 at 22:40




              @MarkusT. Yeah, I noticed your other "community" is stackoverflow, and figured you're likely heading in this direction (but for this type of stuff, python might not be your best choice:)
              – John Forkosh
              Jul 26 at 22:40












              I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
              – Markus T.
              Jul 26 at 23:16




              I thought about that, but If I only need to call the quaternion once wouldn't it not be that bad? The plan is that I'm given a vector and I need to move a robotic arm to that position based on the quaternion. In that regard would I really need to iterate through the program that much?
              – Markus T.
              Jul 26 at 23:16












              @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
              – John Forkosh
              Jul 27 at 8:46




              @MarkusT. Sure, if you're only doing it a few times, python (or an abacus, for that matter:) "wouldn't be that bad".
              – John Forkosh
              Jul 27 at 8:46










              up vote
              0
              down vote













              Yes, the rotation axis is oriented by the vector orthogonal to the two vectors, but we have to use a normalized vector $$vec u=fracvec a times vec bvec b$$, and the angle $theta$ of rotation is obtained from the inner product of the two vectors as you have done.



              The matrix that represents the rotation around the axis $vec u$ of angle $theta$ is given here.






              share|cite|improve this answer

























                up vote
                0
                down vote













                Yes, the rotation axis is oriented by the vector orthogonal to the two vectors, but we have to use a normalized vector $$vec u=fracvec a times vec bvec b$$, and the angle $theta$ of rotation is obtained from the inner product of the two vectors as you have done.



                The matrix that represents the rotation around the axis $vec u$ of angle $theta$ is given here.






                share|cite|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Yes, the rotation axis is oriented by the vector orthogonal to the two vectors, but we have to use a normalized vector $$vec u=fracvec a times vec bvec b$$, and the angle $theta$ of rotation is obtained from the inner product of the two vectors as you have done.



                  The matrix that represents the rotation around the axis $vec u$ of angle $theta$ is given here.






                  share|cite|improve this answer













                  Yes, the rotation axis is oriented by the vector orthogonal to the two vectors, but we have to use a normalized vector $$vec u=fracvec a times vec bvec b$$, and the angle $theta$ of rotation is obtained from the inner product of the two vectors as you have done.



                  The matrix that represents the rotation around the axis $vec u$ of angle $theta$ is given here.







                  share|cite|improve this answer













                  share|cite|improve this answer



                  share|cite|improve this answer











                  answered Jul 26 at 20:28









                  Emilio Novati

                  50.2k43170




                  50.2k43170




















                      up vote
                      0
                      down vote













                      If you look at
                      https://wikimedia.org/api/rest_v1/media/math/render/svg/f259f80a746ee20d481f9b7f600031084358a27c
                      formula from wikipedia(I don't have enough rep to include the image)



                      we obtain the general formula for a rotation matrix about an axis defined by the vector $(u_x,u_y,u_z)$. As you said, we obtain the angle between two vectors $v$ and $w$ with $fracvcdot wv$ and plug that in for theta. Then we take $vtimes w$ to be the vector $u$.






                      share|cite|improve this answer

























                        up vote
                        0
                        down vote













                        If you look at
                        https://wikimedia.org/api/rest_v1/media/math/render/svg/f259f80a746ee20d481f9b7f600031084358a27c
                        formula from wikipedia(I don't have enough rep to include the image)



                        we obtain the general formula for a rotation matrix about an axis defined by the vector $(u_x,u_y,u_z)$. As you said, we obtain the angle between two vectors $v$ and $w$ with $fracvcdot wv$ and plug that in for theta. Then we take $vtimes w$ to be the vector $u$.






                        share|cite|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          If you look at
                          https://wikimedia.org/api/rest_v1/media/math/render/svg/f259f80a746ee20d481f9b7f600031084358a27c
                          formula from wikipedia(I don't have enough rep to include the image)



                          we obtain the general formula for a rotation matrix about an axis defined by the vector $(u_x,u_y,u_z)$. As you said, we obtain the angle between two vectors $v$ and $w$ with $fracvcdot wv$ and plug that in for theta. Then we take $vtimes w$ to be the vector $u$.






                          share|cite|improve this answer













                          If you look at
                          https://wikimedia.org/api/rest_v1/media/math/render/svg/f259f80a746ee20d481f9b7f600031084358a27c
                          formula from wikipedia(I don't have enough rep to include the image)



                          we obtain the general formula for a rotation matrix about an axis defined by the vector $(u_x,u_y,u_z)$. As you said, we obtain the angle between two vectors $v$ and $w$ with $fracvcdot wv$ and plug that in for theta. Then we take $vtimes w$ to be the vector $u$.







                          share|cite|improve this answer













                          share|cite|improve this answer



                          share|cite|improve this answer











                          answered Jul 26 at 21:16









                          Alex

                          1




                          1






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f2863768%2fhow-to-rotate-a-vector-about-an-arbitrary-axis-in-3d-to-align-two-vectors%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Comments

                              Popular posts from this blog

                              Color the edges and diagonals of a regular polygon

                              Relationship between determinant of matrix and determinant of adjoint?

                              What is the equation of a 3D cone with generalised tilt?