[go: up one dir, main page]

File: quat2euler.txt

package info (click to toggle)
coin3 4.0.3%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 54,428 kB
  • sloc: cpp: 256,086; ansic: 21,309; makefile: 8,661; sh: 3,141; perl: 1,504; lex: 1,372; lisp: 1,247; pascal: 961; xml: 604; yacc: 387; sed: 68
file content (178 lines) | stat: -rw-r--r-- 6,626 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

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" <mark.everett@virgin.net> 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
matrix, 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 doesn't 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.

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