Don Hatch (hatch++at++hell.engr.sgi.com)
Tue, 15 Sep 1998 14:16:59 -0700
Oh, I see what happened, some rows and signs got mixed up.
I think it's supposed to be something like this:
> > void matrix_get_rot( MATRIX mat, float * xrot, float * yrot, float *
> > zrot )
> > {
> > double cp;
> >
> > cp = sqrt( mat[1][0]*mat[1][0] + mat[1][1]*mat[1][1] );
> >
> > if( cp > 16 * FLT_EPSILON ) {
> >
> > *yrot = atan2f( -mat[0][2], mat[2][2] ); // roll
> > *xrot = atan2f( mat[1][2], cp ); // pitch
> > *zrot = atan2f( -mat[1][0], mat[1][1] ); // heading
> > }
> > else
> > ...
This seems correct, but it is unstable near pitch = 90 degrees--
unstable in the sense that converting mat -> HPR -> mat can give
a drastically different matrix from the one you started with,
due to small errors/non-orthogonalities
in the matrix entries; this should NEVER happen.
Example:
Say you start with a matrix expressing pitch=90 degrees:
[1 0 0]
[0 0 1]
[0 -1 0]
Now introduce a small error E (bigger than 16*FLT_EPSILON, whatever
that means):
[1 0 0]
[E 0 1]
[0 -1 0]
Then your algorithm will do this:
cp = sqrt(E*E + 0*0)
= E;
*yrot = atan2f(0, 0) // roll
= 0; // somewhat arbitrarily
*xrot = atan2f(1, E) // pitch
= 90 degrees (give or take E radians)
*zrot = atan2f(-E, 0) // heading
= -90 degrees // !! BAD !!
Converting back to matrix form, this gives:
[ 0 -1 0]
[-E 0 1]
[-1 0 0]
which is very severely wrong!
What's happening here is, if you have a matrix in which
the pitch is near 90 degrees, then the heading and roll
become ambiguous/unstable, but *not* independently so.
I.e. given such a matrix, you can pick either roll or heading arbitrarily,
but once you do that, the other of these two variables is then
completely determined in terms of the one you picked.
Performer's algorithm works this way-- it chooses roll,
and then it calculates heading robustly in terms of it.
In contrast, any algorithm that calculates heading and roll
independently, directly from the matrix,
is going to be unstable (as in the above example).
Don
-- Don Hatch hatch++at++sgi.com (650) 933-5150 Silicon Graphics, Inc.
This archive was generated by hypermail 2.0b2 on Tue Sep 15 1998 - 14:17:03 PDT