Hi!
I know this topic has been discussed, but I found some weird
results.
Retrieving an AxisAngle4d from a Transform3D transform should work like this:
Quat4d rotQuat = new Quat4d();
transform.get(rotQuat);
AxisAngle4d rotation= new AxisAngle4d();
rotation.set(rotQuat);
or
Quat4d rotQuat = new Quat4d();
Vector3d anyTranslation = new Vector3d();
transform.get(rotQuat, anyTranslation);
AxisAngle4d rotation= new AxisAngle4d();
rotation.set(rotQuat);
However, under certain circumstances the resulting rotation in the
AxisAngle4d is a null rotation (0.0 1.0 0.0 0.0), even though there is
a non-null rotation in the transformation matrix.
Extracting the rotation with the following rough method works correctly:
public static AxisAngle4d extractRot(Transform3D trans)
{
AxisAngle4d a = new AxisAngle4d();
Matrix3d r = new Matrix3d();
trans.get(r);
// calculate angle
double calc = (r.m00 + r.m11 + r.m22-1)/2;
if(calc>1.0) calc = 1.0;
else if(calc<-1.0) calc = -1.0;
a.angle = Math.acos(calc);
// No angle equals no rotation, so we are done
if(a.angle==0.0) return new AxisAngle4d(0,1,0,0);
// calculate axis (note that we have to handle the case of angle==PI
seperately!)
double delta= 0.01; // accuracy of the equality check
if(a.angle<=Math.PI+delta && a.angle>=Math.PI-delta) {
if(r.m00>=r.m11 && r.m00>=r.m22) {
a.x = (Math.sqrt(r.m00 - r.m11 - r.m22 +1))/2.0;
a.y = r.m01 / (2*a.x);
a.z = r.m02 / (2*a.x);
} else if(r.m11>=r.m00 && r.m11>=r.m22) {
a.y = (Math.sqrt(r.m11 - r.m00 - r.m22 +1))/2.0;
a.x = r.m01 / (2*a.y);
a.z = r.m12 / (2*a.y);
} else if(r.m22>=r.m11 && r.m22>=r.m00) {
a.z = (Math.sqrt(r.m22 - r.m00 - r.m11 +1))/2.0;
a.x = r.m02 / (2*a.z);
a.y = r.m12 / (2*a.z);
}
} else {
Vector3d v = new Vector3d(r.m21-r.m12, r.m02-r.m20, r.m10-r.m01);
double len = v.length();
Vector3d u = new Vector3d(v.x/len, v.y/len, v.z/len);
a.x = u.x;
a.y = u.y;
a.z = u.z;
}
return a;
}
Consider the following transformation matrix:
Matrix4d mat = new Matrix4d(0.9999999999994165, 1.0799814313528522E-6,
6.437206877160347E-14, -221.0680620796118,
1.0799814313528522E-6, -1.0000001192084251, -5.83057446579071E-13,
137.63260064886325,
-6.437206898336171E-14, 5.830574465790711E-13, -1.0000001192090082,
379.91844909062524,
0.0, 0.0, 0.0, 1.0);
transform.set(mat);
The first way retrieves an AxisAngle4d of
0.0 1.0 0.0 0.0
while the above method correctly extracts:
1.0000000298021061 5.399906995835662E-7 3.2186033426590167E-14
3.141592653589793
However, explicitly generating a transformation with
AxisAngle4d aa = new AxisAngle4d(1.0000000298021061, 5.399906995835662E-7,
3.2186033426590167E-14, 3.141592653589793);
transform.setRotation(aa);
and retrieving the rotation back with the first method results in correct
values.
It's just in these cases like the above transformation matrix.
Best regards,
Roland
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".