DirectX 9 rotations. 
Author Message
 DirectX 9 rotations.

I have been using OpenGL lately for my graphics.  To do rotations on the
screen I used the Rotate X,Y,or Z command.  What I found is that there is a
sticking point where your rotations go nuts.  To get around this I had to use
a confusing matrix rotation class.  Anyway, my question is, does DirectX 9
have the matrix rotations that avoids this problem?


Mon, 20 Jun 2005 22:18:57 GMT  
 DirectX 9 rotations.
thats called gimbal lock, and is a weakness of using euler angles to control
rotations.

try using quaternions.


Quote:
> I have been using OpenGL lately for my graphics.  To do rotations on the
> screen I used the Rotate X,Y,or Z command.  What I found is that there is
a
> sticking point where your rotations go nuts.  To get around this I had to
use
> a confusing matrix rotation class.  Anyway, my question is, does DirectX 9
> have the matrix rotations that avoids this problem?



Tue, 21 Jun 2005 03:29:16 GMT  
 DirectX 9 rotations.
No, I fixed the problem with OpenGL.  My question was about direct X 9.  Does
direct x 9 fix this problem?


Tue, 21 Jun 2005 04:35:11 GMT  
 DirectX 9 rotations.
its not something the underlying implementation knows about, its a math
problem related to how you treat rotations in your code, and your "confusing
matrix class" contained the fix.


Quote:
> No, I fixed the problem with OpenGL.  My question was about direct X 9.
Does
> direct x 9 fix this problem?



Tue, 21 Jun 2005 05:12:23 GMT  
 DirectX 9 rotations.
OK I just need a yes or no on this one because I don't follow you.

1. With directx 9, do I have to use quaternions to avoid gimbal lock?

2. Does DirectX 9 have built in quaternions in its rotation calls?

If I have to write the code for quaternions to do my rotations, is there and
example of this in the SDK that you know about?



Tue, 21 Jun 2005 06:23:52 GMT  
 DirectX 9 rotations.


Quote:
> OK I just need a yes or no on this one because I don't follow you.

> 1. With directx 9, do I have to use quaternions to avoid gimbal lock?

there are several techniques to avoid gimbal lock, quaternions are one of
them. performing a google search on gimbal lock might prove illuminating.

Quote:

> 2. Does DirectX 9 have built in quaternions in its rotation calls?

D3DX does provide quaternion support. several articles are around that
describe using quaternions, a google search will be useful.

Quote:

> If I have to write the code for quaternions to do my rotations, is there
and
> example of this in the SDK that you know about?



Tue, 21 Jun 2005 08:46:08 GMT  
 DirectX 9 rotations.
Alright, all I need to do is search google everytime I have a question.  I
just typed in quaternions and got a million hits.  Now I can search through
all these pages for the next three months looking for what I need.  I am glad
you pointed me to google.


says...

Quote:



>> OK I just need a yes or no on this one because I don't follow you.

>> 1. With directx 9, do I have to use quaternions to avoid gimbal lock?

>there are several techniques to avoid gimbal lock, quaternions are one of
>them. performing a google search on gimbal lock might prove illuminating.

>> 2. Does DirectX 9 have built in quaternions in its rotation calls?

>D3DX does provide quaternion support. several articles are around that
>describe using quaternions, a google search will be useful.

>> If I have to write the code for quaternions to do my rotations, is there
>and
>> example of this in the SDK that you know about?



Tue, 21 Jun 2005 22:39:04 GMT  
 DirectX 9 rotations.
Hi,

DirectX also has the possibility to allow you to directly make the rotation about an axis, through

D3DXMatrixRotationAxis( _
    MOut As D3DMATRIX, _
    VAxis As D3DVECTOR, _
    angle As Single)

where VAxis is the vector describing the direction around which you turn of the specified angle, it
does not need to be a unit length vector (D3DMatrixRotationAxis seems to normalize it anyhow).

===========
Option Explicit

Public Sub RotAxis()

    ' Rotate through the axis (1, 1, 1)
Dim Mat As D3DMATRIX
Dim Vec As D3DVECTOR
Dim theta As Single

    theta = 0.1 ' about 6 degree
    Vec.x = (3#) ^ -0.5
    Vec.y = (3#) ^ -0.5
    Vec.z = (1 - Vec.x ^ 2 - Vec.y ^ 2) ^ 0.5

    D3DXMatrixRotationAxis Mat, Vec, theta
    PrintMat Mat

    Debug.Print "  compared to 3 individual rotations ... "

Dim mx As D3DMATRIX
Dim my As D3DMATRIX
Dim mz As D3DMATRIX
Dim mres As D3DMATRIX

    D3DXMatrixRotationX mx, theta * Vec.x
    D3DXMatrixRotationY my, theta * Vec.y
    D3DXMatrixRotationZ mz, theta * Vec.z
    D3DXMatrixMultiply mres, my, mx
    D3DXMatrixMultiply mres, mz, mres
    PrintMat mres ' =  [mz][my][mx]

End Sub

Public Sub PrintMat(Mat As D3DMATRIX)
Const cc = " 0.0000E+00;-0.0000E-00"

    Debug.Print Format(Mat.m11, cc), Format(Mat.m12, cc), Format(Mat.m13, cc), Format(Mat.m14, cc)
    Debug.Print Format(Mat.m21, cc), Format(Mat.m22, cc), Format(Mat.m23, cc), Format(Mat.m24, cc)
    Debug.Print Format(Mat.m31, cc), Format(Mat.m32, cc), Format(Mat.m33, cc), Format(Mat.m34, cc)
    Debug.Print Format(Mat.m41, cc), Format(Mat.m42, cc), Format(Mat.m43, cc), Format(Mat.m44, cc)
End Sub

=============

Since matrix multiplication is NOT commutative, [A][B] <> [B][A], in general, there is a
fundamental problem using "projected rotation" on the X, Y and Z axis, like here up,  making three
steps: a rotation of theta * Vec.x around X, then, theta * Vec.y around Y and theta * Vec.z around
Z, since the order of the steps will result in a different result, rather than making the initially
desired rotation in just one step. That is a problem of miss-conception, or, if you prefer, a wrong
intuition: rotations cannot be projected into components, since rotations are not vector; rotations
do not add like vectors, they do not obey the parallelogram law, when "added".

Vanderghast, Access MVP



Quote:



> > OK I just need a yes or no on this one because I don't follow you.

> > 1. With directx 9, do I have to use quaternions to avoid gimbal lock?

> there are several techniques to avoid gimbal lock, quaternions are one of
> them. performing a google search on gimbal lock might prove illuminating.

> > 2. Does DirectX 9 have built in quaternions in its rotation calls?

> D3DX does provide quaternion support. several articles are around that
> describe using quaternions, a google search will be useful.

> > If I have to write the code for quaternions to do my rotations, is there
> and
> > example of this in the SDK that you know about?



Tue, 21 Jun 2005 23:17:13 GMT  
 DirectX 9 rotations.
Thanks for your explanation.


Wed, 22 Jun 2005 00:54:43 GMT  
 DirectX 9 rotations.
I would need a little clarification here. It seems most people saying they
"avoided gimble locking by using quaternions instead of matrices". It looks
like to me that this is not a problem that comes really from matrix math but
rather from the way to construct the matrices (basically constructing each
time a matrix from yaw, pitch, roll values instead of always working on
matrices and extracting these values).

In particular does matrix math itself suffers from the gimble lock problem
or would the exact phrasing be rather "*if* you are constructing your
matrices this way, you'll have the gimble lock problem and you should either
use matrix math this (other) way *or* use quaternions if you prefer still to
work starting with yaw, pitch, roll values".

Any good well known paper on "gimble locking" ? TIA for any help.

Patrice

[cut]

Quote:

> Since matrix multiplication is NOT commutative, [A][B] <> [B][A], in
general, there is a
> fundamental problem using "projected rotation" on the X, Y and Z axis,

like here up,  making three
Quote:
> steps: a rotation of theta * Vec.x around X, then, theta * Vec.y around Y

and theta * Vec.z around
Quote:
> Z, since the order of the steps will result in a different result, rather

than making the initially
Quote:
> desired rotation in just one step. That is a problem of miss-conception,

or, if you prefer, a wrong
Quote:
> intuition: rotations cannot be projected into components, since rotations

are not vector; rotations
Quote:
> do not add like vectors, they do not obey the parallelogram law, when
"added".

> Vanderghast, Access MVP

[cut]


Wed, 22 Jun 2005 21:44:33 GMT  
 DirectX 9 rotations.
Hi Patrice,

The second option is to be applied since a quaternion is representable with
matrix, mathematically, the first option seems to be not logical (in the
mathematical meaning :-)  ).

========Quote

A quaternion has four components,
which can be written [(x,y,z),w],

(...)

BTW, quaternions can also be represented by matrices

  a' -b
 b' a

where a=x+iy, b=z+iw; a',b': conjugates of a,b.
======== Huayong ========= /Quote

The third option is mathematically equivalent to the second option ( we can
derive a quaternion from matrix and matrix from quaternion), I even think
there are DirectX  utilities functions that cover that. If not, here some C
code

=========Quote===========

Hope it helps,
Mike Goza

/***************************************************************************
*
 *
 *  Quaternion_to_Matrix - computes the 3x3 rotation matrix based on the
 *                         supplied quaternion.
 *
 *  Args:  mat - matrix to return
 *         sval - real part of quaternion
 *         vec - vector part of quaternion
 *

****************************************************************************
/
void
Quaternion_to_Matrix(DMATRIX mat, double sval, double *vec)
{
   mat[0][0] = 1.0L - 2.0L * (vec[1] * vec[1] + vec[2] * vec[2]);
   mat[0][1] = 2.0L * (vec[0] * vec[1] - sval * vec[2]);
   mat[0][2] = 2.0L * (vec[0] * vec[2] + sval * vec[1]);

   mat[1][0] = 2.0L * (vec[0] * vec[1] + sval * vec[2]);
   mat[1][1] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[2] * vec[2]);
   mat[1][2] = 2.0L * (vec[1] * vec[2] - sval * vec[0]);

   mat[2][0] = 2.0L * (vec[0] * vec[2] - sval * vec[1]);
   mat[2][1] = 2.0L * (vec[1] * vec[2] + sval * vec[0]);
   mat[2][2] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[1] * vec[1]);

Quote:
}

/***************************************************************************
**
 *
 *  Matrix_to_Quaternion - computes a quaternion from the matrix
 *
 *  Args:  mat - 3x3 matrix
 *         sval - real part of quaternion
 *         vec - vector part of quaternion
 *
 *

****************************************************************************
/
void
Matrix_to_Quaternion(double *sval, double *vec, DMATRIX mat)
{
   double temp, tr;
   register i;

   tr = mat[0][0] + mat[1][1] + mat[2][2];

   if(tr >= 0.0L) {
      temp = sqrt(tr + 1.0L);
      *sval = 0.5L * temp;
      temp = 0.5L / temp;
      vec[0] = (mat[2][1] - mat[1][2]) * temp;
      vec[1] = (mat[0][2] - mat[2][0]) * temp;
      vec[2] = (mat[1][0] - mat[0][1]) * temp;
   }
   else {
      i = 0;
      if(mat[1][1] > mat[0][0])
         i = 1;
      if(mat[2][2] > mat[i][i])
         i = 2;

      switch(i) {
         case 0:
            temp = sqrt( (mat[0][0] - (mat[1][1] + mat[2][2])) + 1.0L);
            vec[0] = 0.5L * temp;
            temp = 0.5L / temp;
            vec[1] = (mat[0][1] + mat[1][0]) * temp;
            vec[2] = (mat[2][0] + mat[0][2]) * temp;
            *sval = (mat[2][1] - mat[1][2]) * temp;
            break;

         case 1:
            temp = sqrt( (mat[1][1] - (mat[2][2] + mat[0][0])) + 1.0L);
            vec[1] = 0.5L * temp;
            temp = 0.5L / temp;
            vec[2] = (mat[1][2] + mat[2][1]) * temp;
            vec[0] = (mat[0][1] + mat[1][0]) * temp;
            *sval = (mat[0][2] - mat[2][0]) * temp;
            break;

         case 2:
            temp = sqrt( (mat[2][2] - (mat[0][0] + mat[1][1])) + 1.0L);
            vec[2] = 0.5L * temp;
            temp = 0.5L / temp;
            vec[0] = (mat[2][0] + mat[0][2]) * temp;
            vec[1] = (mat[1][2] + mat[2][1]) * temp;
            *sval = (mat[1][0] - mat[0][1]) * temp;
            break;
      }
   }

Quote:
}

==============/Quote ===============

I do not have what I consider a very good article about the gimbal lock,
short of some trying to describe the possible lost of one degree of freedom.
Here, one of the most "concise".

================Quote==============
( Advanced 3-D Game Programming Using DirectX 8.0, WordWare Publishing inc,
Peter Walsh, end of page 177)

    Gimbal lock pops up when you're using the first method described above.
Imagine that you perfomr a yaw rotation first, then pitch, then roll. Alos,
say the yaw and pitch rotations are both a quater-turn (this could come up
quite easily in a game like Descent). So, imagine you perfomr the first
rotation, which takes you form pointing forward to pointing up. The second
rotation spins you around the y axis 90 degree, so your're still facing up
but your up up direction is now to the right, not backward.
    Now comes the lock. When you go to do the roll rotation, which way will
it turn you? About the z axis, or course. However, given any roll value, you
can reach the same final rotation just by changing [using initial] yaw and
pitch. So essentially, you have lost a degree of freedom. This,  as you
should expect, is bad.
====================/Quote ===========

I dissagree with Peter on his claim that numerical imprecision also creates
a signifiant problem ( his argument is not reproduced here). Two
translations, [Tx] and [Ty], clearly have [Tx][Ty] = [Ty][Tx]
(commutativity hold for translations, or, if you prefer, one can be done,
then the other, and the result is the same if the order is reversed), but we
do not have that relation for matrix representation for rotations (in
general). Sure, numerical imprecisions are important for small angles, but
gimbal lock can occur without that, as Peter described it in his example we
quoted, where numbers are purely all 1 and 0, in magnitude (using angles of
90 degree, exactly).

As I said, I do not have a clean concise article about gimbal lock that
"satisfy" my whole curiosity, but I am left on the impression that it is
originally a particular case of the more general one:  rotations do not add
vectorially, so, we have to be careful about how we (intuitively) use
"components" of a rotation. In other word, a rotation around an axis has no
equivalence about a decomposition of rotation about three (orthogonal) axis.
A length may have component, a rotation does not (unless it is a limit to
infinity small).

If you fall on some highlighting concise stuff that covers other relevant
aspect I didn't report, fell free to post its reference, it will be
appreciated.

Vanderghast, Access MVP

Quote:

> I would need a little clarification here. It seems most people saying they
> "avoided gimble locking by using quaternions instead of matrices". It looks
> like to me that this is not a problem that comes really from matrix math but
> rather from the way to construct the matrices (basically constructing each
> time a matrix from yaw, pitch, roll values instead of always working on
> matrices and extracting these values).

> In particular does matrix math itself suffers from the gimble lock problem
> or would the exact phrasing be rather "*if* you are constructing your
> matrices this way, you'll have the gimble lock problem and you should either
> use matrix math this (other) way *or* use quaternions if you prefer still to
> work starting with yaw, pitch, roll values".

> Any good well known paper on "gimble locking" ? TIA for any help.

> Patrice

> [cut]

> > Since matrix multiplication is NOT commutative, [A][B] <> [B][A], in
> general, there is a
> > fundamental problem using "projected rotation" on the X, Y and Z axis,
> like here up,  making three
> > steps: a rotation of theta * Vec.x around X, then, theta * Vec.y around Y
> and theta * Vec.z around
> > Z, since the order of the steps will result in a different result, rather
> than making the initially
> > desired rotation in just one step. That is a problem of miss-conception,
> or, if you prefer, a wrong
> > intuition: rotations cannot be projected into components, since rotations
> are not vector; rotations
> > do not add like vectors, they do not obey the parallelogram law, when
> "added".

> > Vanderghast, Access MVP

> [cut]



Sat, 25 Jun 2005 00:42:15 GMT  
 DirectX 9 rotations.
one of the Alan Watt books also discusses gimbal lock.


Quote:
> Hi Patrice,

> The second option is to be applied since a quaternion is representable
with
> matrix, mathematically, the first option seems to be not logical (in the
> mathematical meaning :-)  ).

> ========Quote

> A quaternion has four components,
> which can be written [(x,y,z),w],

> (...)

> BTW, quaternions can also be represented by matrices

>   a' -b
>  b' a

> where a=x+iy, b=z+iw; a',b': conjugates of a,b.
> ======== Huayong ========= /Quote

> The third option is mathematically equivalent to the second option ( we
can
> derive a quaternion from matrix and matrix from quaternion), I even think
> there are DirectX  utilities functions that cover that. If not, here some
C
> code

> =========Quote===========

> Hope it helps,
> Mike Goza


/***************************************************************************
Quote:
> *
>  *
>  *  Quaternion_to_Matrix - computes the 3x3 rotation matrix based on the
>  *                         supplied quaternion.
>  *
>  *  Args:  mat - matrix to return
>  *         sval - real part of quaternion
>  *         vec - vector part of quaternion
>  *

****************************************************************************

- Show quoted text -

Quote:
> /
> void
> Quaternion_to_Matrix(DMATRIX mat, double sval, double *vec)
> {
>    mat[0][0] = 1.0L - 2.0L * (vec[1] * vec[1] + vec[2] * vec[2]);
>    mat[0][1] = 2.0L * (vec[0] * vec[1] - sval * vec[2]);
>    mat[0][2] = 2.0L * (vec[0] * vec[2] + sval * vec[1]);

>    mat[1][0] = 2.0L * (vec[0] * vec[1] + sval * vec[2]);
>    mat[1][1] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[2] * vec[2]);
>    mat[1][2] = 2.0L * (vec[1] * vec[2] - sval * vec[0]);

>    mat[2][0] = 2.0L * (vec[0] * vec[2] - sval * vec[1]);
>    mat[2][1] = 2.0L * (vec[1] * vec[2] + sval * vec[0]);
>    mat[2][2] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[1] * vec[1]);
> }

/***************************************************************************
Quote:
> **
>  *
>  *  Matrix_to_Quaternion - computes a quaternion from the matrix
>  *
>  *  Args:  mat - 3x3 matrix
>  *         sval - real part of quaternion
>  *         vec - vector part of quaternion
>  *
>  *

****************************************************************************

- Show quoted text -

Quote:
> /
> void
> Matrix_to_Quaternion(double *sval, double *vec, DMATRIX mat)
> {
>    double temp, tr;
>    register i;

>    tr = mat[0][0] + mat[1][1] + mat[2][2];

>    if(tr >= 0.0L) {
>       temp = sqrt(tr + 1.0L);
>       *sval = 0.5L * temp;
>       temp = 0.5L / temp;
>       vec[0] = (mat[2][1] - mat[1][2]) * temp;
>       vec[1] = (mat[0][2] - mat[2][0]) * temp;
>       vec[2] = (mat[1][0] - mat[0][1]) * temp;
>    }
>    else {
>       i = 0;
>       if(mat[1][1] > mat[0][0])
>          i = 1;
>       if(mat[2][2] > mat[i][i])
>          i = 2;

>       switch(i) {
>          case 0:
>             temp = sqrt( (mat[0][0] - (mat[1][1] + mat[2][2])) + 1.0L);
>             vec[0] = 0.5L * temp;
>             temp = 0.5L / temp;
>             vec[1] = (mat[0][1] + mat[1][0]) * temp;
>             vec[2] = (mat[2][0] + mat[0][2]) * temp;
>             *sval = (mat[2][1] - mat[1][2]) * temp;
>             break;

>          case 1:
>             temp = sqrt( (mat[1][1] - (mat[2][2] + mat[0][0])) + 1.0L);
>             vec[1] = 0.5L * temp;
>             temp = 0.5L / temp;
>             vec[2] = (mat[1][2] + mat[2][1]) * temp;
>             vec[0] = (mat[0][1] + mat[1][0]) * temp;
>             *sval = (mat[0][2] - mat[2][0]) * temp;
>             break;

>          case 2:
>             temp = sqrt( (mat[2][2] - (mat[0][0] + mat[1][1])) + 1.0L);
>             vec[2] = 0.5L * temp;
>             temp = 0.5L / temp;
>             vec[0] = (mat[2][0] + mat[0][2]) * temp;
>             vec[1] = (mat[1][2] + mat[2][1]) * temp;
>             *sval = (mat[1][0] - mat[0][1]) * temp;
>             break;
>       }
>    }
> }
> ==============/Quote ===============

> I do not have what I consider a very good article about the gimbal lock,
> short of some trying to describe the possible lost of one degree of
freedom.
> Here, one of the most "concise".

> ================Quote==============
> ( Advanced 3-D Game Programming Using DirectX 8.0, WordWare Publishing
inc,
> Peter Walsh, end of page 177)

>     Gimbal lock pops up when you're using the first method described
above.
> Imagine that you perfomr a yaw rotation first, then pitch, then roll.
Alos,
> say the yaw and pitch rotations are both a quater-turn (this could come up
> quite easily in a game like Descent). So, imagine you perfomr the first
> rotation, which takes you form pointing forward to pointing up. The second
> rotation spins you around the y axis 90 degree, so your're still facing up
> but your up up direction is now to the right, not backward.
>     Now comes the lock. When you go to do the roll rotation, which way
will
> it turn you? About the z axis, or course. However, given any roll value,
you
> can reach the same final rotation just by changing [using initial] yaw and
> pitch. So essentially, you have lost a degree of freedom. This,  as you
> should expect, is bad.
> ====================/Quote ===========

> I dissagree with Peter on his claim that numerical imprecision also
creates
> a signifiant problem ( his argument is not reproduced here). Two
> translations, [Tx] and [Ty], clearly have [Tx][Ty] = [Ty][Tx]
> (commutativity hold for translations, or, if you prefer, one can be done,
> then the other, and the result is the same if the order is reversed), but
we
> do not have that relation for matrix representation for rotations (in
> general). Sure, numerical imprecisions are important for small angles, but
> gimbal lock can occur without that, as Peter described it in his example
we
> quoted, where numbers are purely all 1 and 0, in magnitude (using angles
of
> 90 degree, exactly).

> As I said, I do not have a clean concise article about gimbal lock that
> "satisfy" my whole curiosity, but I am left on the impression that it is
> originally a particular case of the more general one:  rotations do not
add
> vectorially, so, we have to be careful about how we (intuitively) use
> "components" of a rotation. In other word, a rotation around an axis has
no
> equivalence about a decomposition of rotation about three (orthogonal)
axis.
> A length may have component, a rotation does not (unless it is a limit to
> infinity small).

> If you fall on some highlighting concise stuff that covers other relevant
> aspect I didn't report, fell free to post its reference, it will be
> appreciated.

> Vanderghast, Access MVP




- Show quoted text -

Quote:
> > I would need a little clarification here. It seems most people saying
they
> > "avoided gimble locking by using quaternions instead of matrices". It
looks
> > like to me that this is not a problem that comes really from matrix math
but
> > rather from the way to construct the matrices (basically constructing
each
> > time a matrix from yaw, pitch, roll values instead of always working on
> > matrices and extracting these values).

> > In particular does matrix math itself suffers from the gimble lock
problem
> > or would the exact phrasing be rather "*if* you are constructing your
> > matrices this way, you'll have the gimble lock problem and you should
either
> > use matrix math this (other) way *or* use quaternions if you prefer
still to
> > work starting with yaw, pitch, roll values".

> > Any good well known paper on "gimble locking" ? TIA for any help.

> > Patrice

> > [cut]

> > > Since matrix multiplication is NOT commutative, [A][B] <> [B][A], in
> > general, there is a
> > > fundamental problem using "projected rotation" on the X, Y and Z axis,
> > like here up,  making three
> > > steps: a rotation of theta * Vec.x around X, then, theta * Vec.y
around Y
> > and theta * Vec.z around
> > > Z, since the order of the steps will result in a different result,
rather
> > than making the initially
> > > desired rotation in just one step. That is a problem of
miss-conception,
> > or, if you prefer, a wrong
> > > intuition: rotations cannot be projected into components, since
rotations
> > are not vector; rotations
> > > do not add like vectors, they do not obey the parallelogram law, when
> > "added".

> > > Vanderghast, Access MVP

> > [cut]



Sat, 25 Jun 2005 04:06:52 GMT  
 DirectX 9 rotations.
its using euler angles to generate the matrices that causes the problem.

generating the matrices a different way can solve the problem.

and as I said in the previous post, one of the Alan Watt books has a
description of gimbal lock.


Quote:
> I would need a little clarification here. It seems most people saying they
> "avoided gimble locking by using quaternions instead of matrices". It
looks
> like to me that this is not a problem that comes really from matrix math
but
> rather from the way to construct the matrices (basically constructing each
> time a matrix from yaw, pitch, roll values instead of always working on
> matrices and extracting these values).

> In particular does matrix math itself suffers from the gimble lock problem
> or would the exact phrasing be rather "*if* you are constructing your
> matrices this way, you'll have the gimble lock problem and you should
either
> use matrix math this (other) way *or* use quaternions if you prefer still
to
> work starting with yaw, pitch, roll values".

> Any good well known paper on "gimble locking" ? TIA for any help.

> Patrice

> [cut]

> > Since matrix multiplication is NOT commutative, [A][B] <> [B][A], in
> general, there is a
> > fundamental problem using "projected rotation" on the X, Y and Z axis,
> like here up,  making three
> > steps: a rotation of theta * Vec.x around X, then, theta * Vec.y around
Y
> and theta * Vec.z around
> > Z, since the order of the steps will result in a different result,
rather
> than making the initially
> > desired rotation in just one step. That is a problem of miss-conception,
> or, if you prefer, a wrong
> > intuition: rotations cannot be projected into components, since
rotations
> are not vector; rotations
> > do not add like vectors, they do not obey the parallelogram law, when
> "added".

> > Vanderghast, Access MVP

> [cut]



Sat, 25 Jun 2005 04:08:00 GMT  
 DirectX 9 rotations.

Hi all,

I don't even know who euler was never mind what a
quaternion is. I take it that using euler angles involves
using pythag and sin, cos, tan etc to calculate new
vertices and axes?

I had a problem using the standard rotation and
translation matix functions to create a typical 3d shoot
em up style view translation. If I concatenate the
rotation first, my x and z axes are still aligned to the
world origin, whereas if I concatenate translation first,
my x and z axes are correctly aligned with the rotation,
but rotation takes place around the world origin rather
than the camera origin.

So I thought I should be using the d3dxmatrixlookatlh
function to create a matrix based on "EYE", "AT" and "UP"
vertices using pythag and sin and cos etc to calculate
new trajectories.
Are you guys saying that I should be using quaternions
instead? That I might end up in a bit of a gimbal lock
situation or something?

Am I heading in the wrong direction?
Any help would be appreciated.
Thanks,
Johann

Quote:
>-----Original Message-----
>Hi Patrice,

>The second option is to be applied since a quaternion is
representable with
>matrix, mathematically, the first option seems to be not
logical (in the
>mathematical meaning :-)  ).

>========Quote

>A quaternion has four components,
>which can be written [(x,y,z),w],

>(...)

>BTW, quaternions can also be represented by matrices

>  a' -b
> b' a

>where a=x+iy, b=z+iw; a',b': conjugates of a,b.
>======== Huayong ========= /Quote

>The third option is mathematically equivalent to the

second option ( we can
Quote:
>derive a quaternion from matrix and matrix from

quaternion), I even think

- Show quoted text -

Quote:
>there are DirectX  utilities functions that cover that.
If not, here some C
>code

>=========Quote===========

>Hope it helps,
>Mike Goza

>/********************************************************
*******************
>*
> *
> *  Quaternion_to_Matrix - computes the 3x3 rotation
matrix based on the
> *                         supplied quaternion.
> *
> *  Args:  mat - matrix to return
> *         sval - real part of quaternion
> *         vec - vector part of quaternion
> *

>*********************************************************
*******************
>/
>void
>Quaternion_to_Matrix(DMATRIX mat, double sval, double
*vec)
>{
>   mat[0][0] = 1.0L - 2.0L * (vec[1] * vec[1] + vec[2] *
vec[2]);
>   mat[0][1] = 2.0L * (vec[0] * vec[1] - sval * vec[2]);
>   mat[0][2] = 2.0L * (vec[0] * vec[2] + sval * vec[1]);

>   mat[1][0] = 2.0L * (vec[0] * vec[1] + sval * vec[2]);
>   mat[1][1] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[2] *
vec[2]);
>   mat[1][2] = 2.0L * (vec[1] * vec[2] - sval * vec[0]);

>   mat[2][0] = 2.0L * (vec[0] * vec[2] - sval * vec[1]);
>   mat[2][1] = 2.0L * (vec[1] * vec[2] + sval * vec[0]);
>   mat[2][2] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[1] *
vec[1]);
>}

>/********************************************************
*******************
>**
> *
> *  Matrix_to_Quaternion - computes a quaternion from
the matrix
> *
> *  Args:  mat - 3x3 matrix
> *         sval - real part of quaternion
> *         vec - vector part of quaternion
> *
> *

>*********************************************************
*******************
>/
>void
>Matrix_to_Quaternion(double *sval, double *vec, DMATRIX
mat)
>{
>   double temp, tr;
>   register i;

>   tr = mat[0][0] + mat[1][1] + mat[2][2];

>   if(tr >= 0.0L) {
>      temp = sqrt(tr + 1.0L);
>      *sval = 0.5L * temp;
>      temp = 0.5L / temp;
>      vec[0] = (mat[2][1] - mat[1][2]) * temp;
>      vec[1] = (mat[0][2] - mat[2][0]) * temp;
>      vec[2] = (mat[1][0] - mat[0][1]) * temp;
>   }
>   else {
>      i = 0;
>      if(mat[1][1] > mat[0][0])
>         i = 1;
>      if(mat[2][2] > mat[i][i])
>         i = 2;

>      switch(i) {
>         case 0:
>            temp = sqrt( (mat[0][0] - (mat[1][1] + mat[2]
[2])) + 1.0L);
>            vec[0] = 0.5L * temp;
>            temp = 0.5L / temp;
>            vec[1] = (mat[0][1] + mat[1][0]) * temp;
>            vec[2] = (mat[2][0] + mat[0][2]) * temp;
>            *sval = (mat[2][1] - mat[1][2]) * temp;
>            break;

>         case 1:
>            temp = sqrt( (mat[1][1] - (mat[2][2] + mat[0]
[0])) + 1.0L);
>            vec[1] = 0.5L * temp;
>            temp = 0.5L / temp;
>            vec[2] = (mat[1][2] + mat[2][1]) * temp;
>            vec[0] = (mat[0][1] + mat[1][0]) * temp;
>            *sval = (mat[0][2] - mat[2][0]) * temp;
>            break;

>         case 2:
>            temp = sqrt( (mat[2][2] - (mat[0][0] + mat[1]
[1])) + 1.0L);
>            vec[2] = 0.5L * temp;
>            temp = 0.5L / temp;
>            vec[0] = (mat[2][0] + mat[0][2]) * temp;
>            vec[1] = (mat[1][2] + mat[2][1]) * temp;
>            *sval = (mat[1][0] - mat[0][1]) * temp;
>            break;
>      }
>   }
>}
>==============/Quote ===============

>I do not have what I consider a very good article about
the gimbal lock,
>short of some trying to describe the possible lost of

one degree of freedom.
Quote:
>Here, one of the most "concise".

>================Quote==============
>( Advanced 3-D Game Programming Using DirectX 8.0,

WordWare Publishing inc,
Quote:
>Peter Walsh, end of page 177)

>    Gimbal lock pops up when you're using the first

method described above.
Quote:
>Imagine that you perfomr a yaw rotation first, then

pitch, then roll. Alos,
Quote:
>say the yaw and pitch rotations are both a quater-turn
(this could come up
>quite easily in a game like Descent). So, imagine you
perfomr the first
>rotation, which takes you form pointing forward to

pointing up. The second
Quote:
>rotation spins you around the y axis 90 degree, so

your're still facing up
Quote:
>but your up up direction is now to the right, not
backward.
>    Now comes the lock. When you go to do the roll

rotation, which way will
Quote:
>it turn you? About the z axis, or course. However, given
any roll value, you
>can reach the same final rotation just by changing

[using initial] yaw and
Quote:
>pitch. So essentially, you have lost a degree of

freedom. This,  as you
Quote:
>should expect, is bad.
>====================/Quote ===========

>I dissagree with Peter on his claim that numerical

imprecision also creates
Quote:
>a signifiant problem ( his argument is not reproduced
here). Two
>translations, [Tx] and [Ty], clearly have [Tx][Ty] = [Ty]
[Tx]
>(commutativity hold for translations, or, if you prefer,
one can be done,
>then the other, and the result is the same if the order

is reversed), but we
Quote:
>do not have that relation for matrix representation for
rotations (in
>general). Sure, numerical imprecisions are important for
small angles, but
>gimbal lock can occur without that, as Peter described

it in his example we
Quote:
>quoted, where numbers are purely all 1 and 0, in

magnitude (using angles of
Quote:
>90 degree, exactly).

>As I said, I do not have a clean concise article about
gimbal lock that
>"satisfy" my whole curiosity, but I am left on the

impression that it is
Quote:
>originally a particular case of the more general one:  

rotations do not add
Quote:
>vectorially, so, we have to be careful about how we
(intuitively) use
>"components" of a rotation. In other word, a rotation

around an axis has no
Quote:
>equivalence about a decomposition of rotation about

three (orthogonal) axis.
Quote:
>A length may have component, a rotation does not (unless
it is a limit to
>infinity small).

>If you fall on some highlighting concise stuff that

covers other relevant
Quote:
>aspect I didn't report, fell free to post its reference,
it will be
>appreciated.

>Vanderghast, Access MVP




Quote:
>> I would need a little clarification here. It seems

most people saying they
Quote:
>> "avoided gimble locking by using quaternions instead

of matrices". It looks
Quote:
>> like to me that this is not a problem that comes

really from matrix math but
Quote:
>> rather from the way to construct the matrices

(basically constructing each
Quote:
>> time a matrix from yaw, pitch, roll values instead of
always working on
>> matrices and extracting these values).

>> In particular does matrix math itself suffers from the
gimble lock problem
>> or would the exact phrasing be rather "*if* you are
constructing your
>> matrices this way, you'll have the gimble lock problem

and you should either
Quote:
>> use matrix math this (other) way *or* use quaternions

if you prefer still to
Quote:
>> work starting with yaw, pitch, roll values".

>> Any good well known paper on "gimble locking" ? TIA
for any help.

>> Patrice

>> [cut]

>> > Since matrix multiplication is NOT commutative, [A]
[B] <> [B][A], in
>> general, there is a
>> > fundamental problem using "projected rotation" on

the X, Y and Z axis,
Quote:
>> like here up,  making three
>> > steps: a rotation of theta * Vec.x around X, then,

theta * Vec.y around Y
Quote:
>> and theta * Vec.z around
>> > Z, since the order of the steps will result in a

different result, rather
Quote:
>> than making the initially
>> > desired rotation in just one step. That is a problem
of miss-conception,
>> or, if you prefer, a wrong
>> > intuition: rotations cannot be projected into

components, since rotations
Quote:
>> are not vector; rotations
>> > do not add like vectors, they do not obey the

parallelogram law, when

- Show quoted text -

Quote:
>> "added".

>> > Vanderghast, Access MVP

>> [cut]

>.



Sat, 25 Jun 2005 17:25:49 GMT  
 DirectX 9 rotations.
Hi,

For a rotation through an axis with the direction ( cosx, cosy, cosz )  passing through (sx, sy,
sz), I suggest you first make a translation (to shift the origin at (sx, sy, sz) ), then, make ONE
rotation (not 3, with pitch, roll and  yaw, neither about x, y or z) around the direction, through
the use of the utility function  D3DXMatrixRotationAxis, then, undo the first translation (shift
back the origin). You can concatenate the three matrix:  [-Trans][Rot][Trans]

(where  -  is just a name, but also refer to the fact we use the negative translation values of
what we used in Trans).

==========
Option Explicit

Public Sub Test( ByVal cosx As Single, _
                    ByVal cosy as Single, _
                    ByVal cosz As Single, _
                    ByVal sx As Single, _
                    ByVal sy As Single, _
                    ByVal sz As Single, _
                    ByVal AmountOfRotation As Single)

Dim Direction As D3DVECTOR  '  Direction of the axis around which we turn
Dim Through As D3DVECTOR    '  A point 'fixing' the axis in one position
Dim rotate As Single        '  angle of rotation

    Direction.x= cosx
    Direction.y= cosy
    Direction.z= cosz

    Through.x= sx
    Through.y= sy
    Through.z= sz

    rotate=  AmountOfRotation    'in radians

    '  Explicitly build the matrixes
Dim Trans As D3DMATRIX
Dim Rot As D3DMATRIX
Dim TransBack As D3DMATRIX

    D3DXMatrixTranslation Trans, Through.x, Through.y, Through.z
    D3DXMatrixRotationAxis Rot, Direction, rotate
    D3DXMatrixTranslation Trans, -Through.x, -Through.y, -Through.z

    ' Concatenate the matrixes
Dim temp As D3DMATRIX
Dim result As D3DMATRIX

    D3DXMatrixMultiply temp, Rot, Trans    '[temp]= [Rot][Trans]
    D3DXMatrixMultiply result, TransBack, temp    '[result]= [TransBack][Rot][Trans]

    PrintMat result

End Sub

Public Sub PrintMat(Mat As D3DMATRIX)
Const cc = " 0.0000E+00;-0.0000E-00"

    Debug.Print Format(Mat.m11, cc), Format(Mat.m12, cc), Format(Mat.m13, cc), Format(Mat.m14, cc)
    Debug.Print Format(Mat.m21, cc), Format(Mat.m22, cc), Format(Mat.m23, cc), Format(Mat.m24, cc)
    Debug.Print Format(Mat.m31, cc), Format(Mat.m32, cc), Format(Mat.m33, cc), Format(Mat.m34, cc)
    Debug.Print Format(Mat.m41, cc), Format(Mat.m42, cc), Format(Mat.m43, cc), Format(Mat.m44, cc)
End Sub

================

Euler angles are good for geometry (length), but fail for rotation since rotation around an axis
cannot be decomposed into "components" of 3 rotations (rotx, roty, rotz). If you have just a roll,
just a yaw or just a pitch, that is ok, otherwise, try to find the axis around which you really
turn around, at that instant of the time, and then, make the rotation in ONE step (one step as far
as rotations are concerned, you can make the required translations adjustments in other steps).

A simplified view of using quaternion would be to merge the Direction Vector, with the amount of
rotation, making a sequence of four values:

    Direction.x, Direction.y, Direction.z, rotate

that is a quaternion beast, and use other functions, present in DirectX, to achieve the same math
as did D3DXMatrixRotationAxis, simply, without making mention of the quaternion beast.

Hoping it may help,
Vanderghast, Access MVP


Quote:
> Hi all,

> I don't even know who euler was never mind what a
> quaternion is. I take it that using euler angles involves
> using pythag and sin, cos, tan etc to calculate new
> vertices and axes?

> I had a problem using the standard rotation and
> translation matix functions to create a typical 3d shoot
> em up style view translation. If I concatenate the
> rotation first, my x and z axes are still aligned to the
> world origin, whereas if I concatenate translation first,
> my x and z axes are correctly aligned with the rotation,
> but rotation takes place around the world origin rather
> than the camera origin.

> So I thought I should be using the d3dxmatrixlookatlh
> function to create a matrix based on "EYE", "AT" and "UP"
> vertices using pythag and sin and cos etc to calculate
> new trajectories.
> Are you guys saying that I should be using quaternions
> instead? That I might end up in a bit of a gimbal lock
> situation or something?

> Am I heading in the wrong direction?
> Any help would be appreciated.
> Thanks,
> Johann

> >-----Original Message-----
> >Hi Patrice,

> >The second option is to be applied since a quaternion is
> representable with
> >matrix, mathematically, the first option seems to be not
> logical (in the
> >mathematical meaning :-)  ).

> >========Quote

> >A quaternion has four components,
> >which can be written [(x,y,z),w],

> >(...)

> >BTW, quaternions can also be represented by matrices

> >  a' -b
> > b' a

> >where a=x+iy, b=z+iw; a',b': conjugates of a,b.
> >======== Huayong ========= /Quote

> >The third option is mathematically equivalent to the
> second option ( we can
> >derive a quaternion from matrix and matrix from
> quaternion), I even think
> >there are DirectX  utilities functions that cover that.
> If not, here some C
> >code

> >=========Quote===========

> >Hope it helps,
> >Mike Goza

> >/********************************************************
> *******************
> >*
> > *
> > *  Quaternion_to_Matrix - computes the 3x3 rotation
> matrix based on the
> > *                         supplied quaternion.
> > *
> > *  Args:  mat - matrix to return
> > *         sval - real part of quaternion
> > *         vec - vector part of quaternion
> > *

> >*********************************************************
> *******************
> >/
> >void
> >Quaternion_to_Matrix(DMATRIX mat, double sval, double
> *vec)
> >{
> >   mat[0][0] = 1.0L - 2.0L * (vec[1] * vec[1] + vec[2] *
> vec[2]);
> >   mat[0][1] = 2.0L * (vec[0] * vec[1] - sval * vec[2]);
> >   mat[0][2] = 2.0L * (vec[0] * vec[2] + sval * vec[1]);

> >   mat[1][0] = 2.0L * (vec[0] * vec[1] + sval * vec[2]);
> >   mat[1][1] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[2] *
> vec[2]);
> >   mat[1][2] = 2.0L * (vec[1] * vec[2] - sval * vec[0]);

> >   mat[2][0] = 2.0L * (vec[0] * vec[2] - sval * vec[1]);
> >   mat[2][1] = 2.0L * (vec[1] * vec[2] + sval * vec[0]);
> >   mat[2][2] = 1.0L - 2.0L * (vec[0] * vec[0] + vec[1] *
> vec[1]);
> >}

> >/********************************************************
> *******************
> >**
> > *
> > *  Matrix_to_Quaternion - computes a quaternion from
> the matrix
> > *
> > *  Args:  mat - 3x3 matrix
> > *         sval - real part of quaternion
> > *         vec - vector part of quaternion
> > *
> > *

> >*********************************************************
> *******************
> >/
> >void
> >Matrix_to_Quaternion(double *sval, double *vec, DMATRIX
> mat)
> >{
> >   double temp, tr;
> >   register i;

> >   tr = mat[0][0] + mat[1][1] + mat[2][2];

> >   if(tr >= 0.0L) {
> >      temp = sqrt(tr + 1.0L);
> >      *sval = 0.5L * temp;
> >      temp = 0.5L / temp;
> >      vec[0] = (mat[2][1] - mat[1][2]) * temp;
> >      vec[1] = (mat[0][2] - mat[2][0]) * temp;
> >      vec[2] = (mat[1][0] - mat[0][1]) * temp;
> >   }
> >   else {
> >      i = 0;
> >      if(mat[1][1] > mat[0][0])
> >         i = 1;
> >      if(mat[2][2] > mat[i][i])
> >         i = 2;

> >      switch(i) {
> >         case 0:
> >            temp = sqrt( (mat[0][0] - (mat[1][1] + mat[2]
> [2])) + 1.0L);
> >            vec[0] = 0.5L * temp;
> >            temp = 0.5L / temp;
> >            vec[1] = (mat[0][1] + mat[1][0]) * temp;
> >            vec[2] = (mat[2][0] + mat[0][2]) * temp;
> >            *sval = (mat[2][1] - mat[1][2]) * temp;
> >            break;

> >         case 1:
> >            temp = sqrt( (mat[1][1] - (mat[2][2] + mat[0]
> [0])) + 1.0L);
> >            vec[1] = 0.5L * temp;
> >            temp = 0.5L / temp;
> >            vec[2] = (mat[1][2] + mat[2][1]) * temp;
> >            vec[0] = (mat[0][1] + mat[1][0]) * temp;
> >            *sval = (mat[0][2] - mat[2][0]) * temp;
> >            break;

> >         case 2:
> >            temp = sqrt( (mat[2][2] - (mat[0][0] + mat[1]
> [1])) + 1.0L);
> >            vec[2] = 0.5L * temp;
> >            temp = 0.5L / temp;
> >            vec[0] = (mat[2][0] + mat[0][2]) * temp;
> >            vec[1] = (mat[1][2] + mat[2][1]) * temp;
> >            *sval = (mat[1][0] - mat[0][1]) * temp;
> >            break;
> >      }
> >   }
> >}
> >==============/Quote ===============

> >I do not have what I consider a very good article about
> the gimbal lock,
> >short of some trying to describe the possible lost of
> one degree of freedom.
> >Here, one of the most "concise".

> >================Quote==============
> >( Advanced 3-D Game Programming Using DirectX 8.0,
> WordWare Publishing inc,
> >Peter Walsh, end of page 177)

> >    Gimbal lock pops up when you're using the first
> method described above.
> >Imagine that you perfomr a yaw rotation first, then
> pitch, then roll. Alos,
> >say the yaw and pitch rotations are both a quater-turn
> (this could come up
> >quite easily in a game like Descent). So, imagine you
> perfomr the first
> >rotation, which takes you form pointing forward to
> pointing up. The second
> >rotation spins you around the y axis 90 degree, so
> your're still facing up
> >but your up up direction is now to the right, not
> backward.
> >    Now comes the lock. When you go to do the roll
> rotation, which way will
> >it turn you? About the z axis, or course. However, given
> any roll value, you
> >can reach the same final rotation just by changing
> [using initial] yaw and
> >pitch. So essentially, you have lost a degree of
> freedom. This,  as you
> >should expect, is bad.
> >====================/Quote ===========

> >I dissagree with Peter on his claim that

...

read more »



Sat, 25 Jun 2005 20:44:45 GMT  
 
 [ 15 post ] 

 Relevant Pages 

1. directx 7 rotation

2. Can a Form or 2nd DirectX app be show over top of DirectX App

3. I only downloaded th DirectX SDK which didn't contain documents on DirectX Media

4. Matrix rotation

5. Text Block rotation in a line.

6. Tracking shape position and rotation WHILE moving

7. Table Rotation

8. Image Rotation

9. getting the region of a usercontrol ? (for rotation)

10. page rotation

11. 3D Rotation Points

12. 3d rotation's

 

 
Powered by phpBB® Forum Software