For an excellent starting point: http://en.wikipedia.org/wiki/Conversion_between_Quaternions_and_Euler_angles Write the code directly from this? ============================================================================== From: ron@dorianresearch.com (Ron Levine) Subject: Re: Quat + Eulers + Ang/Axis Newsgroups: comp.graphics.algorithms Date: Wed, 12 Aug 1998 22:57:57 GMT Organization: Dorian Research, Inc. Reply-To: ron@dorianresearch.com Path: Norway.EU.net!uninett.no!howland.erols.net!news-peer.sprintlink.net!news-peer-east.sprintlink.net!news.sprintlink.net!newspeer.monmouth.com!newsfeed.slip.net!news.slip.net!not-for-mail Lines: 152 Message-ID: <35d21da0.1319571@news.slip.net> References: <6qsd1k$4tk$1@nclient5-gui.server.virgin.net> NNTP-Posting-Host: oak-usr1-5-5.dialup.slip.net Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Newsreader: Forte Agent 1.5/32.451 Xref: Norway.EU.net comp.graphics.algorithms:74960 "Mark Everett" wrote: > >I need to do one of the following and cannot find any information on any of >them : > >1 ) Convert a matrix to eulers >2 ) Convert a quat to eulers >3 ) Convert angle-axis to eulers > >Ok some-one out there must have a function to do ONE of these :) > Doing one of them is effectively equivalent to doing all of them. Just to be specific, let us restate your question with mathematical precision: To find the euler rotations that will generate a given rotation. This is a very frequently asked question, and almost never answered, not completely and correctly anyway, because the answer is a bit of a mess. If at all possible, you should arrange your life so that you never NEED to ask this. And it is possible. But if you feel you can't arrange your life that way, then you must first be aware that, for any given coordinate system, there are at least 12 different ways of defining the Euler rotation sequence. Following the lead of a couple of famous authors, (Wigner, Goldstein), physicists have mostly settled on one particular convention, which happens to be used by NO ONE in computer graphics. Computer graphicists stick to a subset of about two possibilities (both different from the most common physics convention), but again there is no uniformity, and there are further conventional choices of row-vector convention versus column-vector convention, right-hand coordinates versus left-hand coordinates, and clockwise rotation convention versus counterclockwise rotation convention, which all would affect any code that you might write to solve it. So you can't just get someone's code from somewhere and expect it to work with your conventions. You really have to understand the mathematics of the problem and do it yourself. Next you must understand that the problem does not have a well-defined solution, even after we have fixed all of our relevant conventions. Mathematically speaking, you cannot parametrize the space of rotations of 3-space by an Euler rotation scheme without severe singularities. (This is the phenomenon that is sometimes called "gimbal lock"). Specifically, there exist infinitely many rotations (precisely, two disjoint one-parameter families of rotations) for which there are infinitely many Euler decompositions. For these singular rotations you can find particular Euler decompositions that produce them, but there is no way you can do this for all rotations in a continuous way. This singularity problem shoots down the Euler representation for many of the purposes for which you might want to find the Euler angles, most notably, for interpolation between rotations. Last month on comp.graphics.algorithms there was a thread "Euler angles...". Mark Penacho posted a semi-correct message indicating the approach you can take to solve for Euler angles from a given rotation marix, but he got some of the conditions regarding the singularities pretty wrong, so if you get his message from Deja News, be sure also to look at my response to it. Hexapod's code, quoted below, tries to follow a similar path. >I did read Hexapod's Matrix and Quat FAQ, the resulting Matrix->Euler >function follows. It doesnt work btw :) > The first problem with Hexapod's code would be, as I stated above, determining whether his choices for all the various conventions match yours. I note that they do not seem to match the convention used, say, in the book on advanced animation techniques by Watt and Watt, a common source on these issues. The second problem is one of accuracy. Note that he decides that it is a singular case if cos(-asin[X][Z]) < .005, an arbitrary cutoff that will introduce inaccuracies that may be too great for your particular problem. (Note also that the fabs call is unnecessary, since any cos you compute in this way is necessarily positive because asin is between -pi/2 and pi/2). The third problem is that his "clamping" provisions are just plain wrong, given that asin returns a value between -pi/2 and pi/2 and atan2 returns a value between -pi and pi. It's clear that if he tested this at all, he must have tested it only for rotations generated by small positive values of the euler angles. Don't trust everything you find on the Web. And for tutorials on math topics and code presented by computer graphics students, trust almost nothing you find on the Web. >/**************************************** > eulerFromMatrix >_____________________________________ > Inputs: > MAT4X4 m > XYZ a > >Outputs: > BOOL >****************************************/ >void eulerFromMatrix( MAT4X4 m, XYZ a ) >{ >FLOAT c, trX, trY; > a[Y] = (FLOAT) -asin( m[X][Z] ); >c = (FLOAT) cos( a[Y] ); >a[Y] = mRadToDeg( a[Y] ); > if( fabs( c ) > 0.005 ) >{ > trX = m[Z][Z] / c; > trY = -m[Y][Z] / c; > a[X] = (FLOAT) atan2( trY, trX ); > a[X] = mRadToDeg( a[X] ); > trX = m[X][X] / c; > trY = -m[X][Y] / c; > a[Z] = (FLOAT) atan2( trY, trX ); > a[Z] = mRadToDeg( a[Z] ); > } >else >{ > a[X] = 0.0f; > trX = m[Y][Y]; > trY = m[Y][X]; > a[Z] = (FLOAT) atan2( trY, trX ); > a[Z] = mRadToDeg( a[Z] ); >} > //X Clamping >if( a[X] < 0.0f ) > a[X] = 0.0f; > if( a[X] > 360.0f ) > a[X] = 360.0f; > //Y Clamping >if( a[Y] < 0.0f ) > a[Y] = 0.0f; > if( a[Y] > 360.0f ) > a[Y] = 360.0f; >//Z Clamping >if( a[Z] < 0.0f ) > a[Z] = 0.0f; > if( a[Z] > 360.0f ) > a[Z] = 360.0f; >} > > ****************************************************** Dorian Research, Inc. http://www.dorianresearch.com Everyone must reinvent the wheel to build his own custom bicycle. *****************************************************