Author 
Message 
John Jenki #1 / 15

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 


Phil Taylor [ATI #2 / 15

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 


John Jenki #3 / 15

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 


Phil Taylor [ATI #4 / 15

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 


John Jenki #5 / 15

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 


Phil Taylor [ATI #6 / 15

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 


John Jenki #7 / 15

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 


Michel Wals #8 / 15

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.0000E00" 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 missconception, 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 


John Jenki #9 / 15

DirectX 9 rotations.
Thanks for your explanation.

Wed, 22 Jun 2005 00:54:43 GMT 


Patrice Scrib #10 / 15

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 missconception,
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 


Michel Wals #11 / 15

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 3D 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 quaterturn (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 missconception, > 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 


Phil Taylor [ATI #12 / 15

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 > *
**************************************************************************** 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 > * > *
**************************************************************************** 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 3D 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 quaterturn (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 missconception, > > 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 


Phil Taylor [ATI #13 / 15

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 missconception, > 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 


johan #14 / 15

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 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 3D 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 quaterturn (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 missconception, >> 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 Quote: >> "added". >> > Vanderghast, Access MVP >> [cut] >.

Sat, 25 Jun 2005 17:25:49 GMT 


Michel Wals #15 / 15

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.0000E00" 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 3D 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 quaterturn > (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 


