Graphics Reference
In-Depth Information
so we can recover the angle of rotation by computing
=cos
−
1
tr
(
M
)
.
−
1
θ
(11.25)
2
Two special cases arise at this point, corresponding to the two ways that
sin
θ
can be zero.
1.
If
=
0, then
any
unit vector serves as an “axis” for the rotation, because
the rotation is the identity matrix.
θ
2.
If
, and thus is the identity, that
is, our rotation
M
must satisfy
M
2
=
I
. From this we find that
M
(
M
+
I
)=
M
2
+
M
=
I
+
M
=
M
+
I
.
θ
=
π
, then
twice
the rotation has angle 2
π
(11.26)
That means that when we multiply
M
by
M
+
I
, every column of
M
+
I
remains unchanged. So any nonzero column of
M
+
I
, when normalized,
can serve as the axis of rotation. We know that at least one column of
M
+
I
is nonzero; otherwise,
M
=
−
I
. But this is impossible, because the
determinant of
−
I
is
−
1, while that of
M
is
+
1.
M
T
to get
In the general case, when
sin
θ
=
0, we can compute
M
−
M
T
=
I
+sin(
)
J
2
M
−
θ
)
J
+(
1
−
cos
θ
v
−
v
(
I
T
+sin(
)
J
T
v
)(
J
2
v
)
T
)
.
θ
+(
1
−
cos
θ
(11.27)
Because
J
T
v
J
v
and
(
J
2
)
T
=
J
2
v
=
−
, this simplifies to
v
M
T
=
2
sin(
M
−
θ
)
J
v
.
(11.28)
Dividing by 2
sin
θ
gives the matrix
J
v
, from which we can recover
. The code
v
is given in Listing 11.2.
Listing 11.2: Code to find the axis and angle from a rotation matrix.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void RotationToAxisAngle(
Mat33 m,
out Vector3D omega,
out double theta)
{
// convert a 3x3 rotation matrix m to an axis-angle representation
theta = Math.acos( (m.trace()-1)/2);
if (
θ
is near zero
)
{
omega = Vector3D(1,0,0); // any vector works
return;
}
if (
θ
π
)
is near
{
int col =
column with largest entry of m in absolute value
;
omega = Vector3D(m[0, col], m[1, col], m[2, col]);
return;
}
else
{
mat 33 s = m - m.transpose();
double x = -s[1,2], y = s[0,2]; z = -s[1,1];