Reputation: 19863
I'm using Catia software. When I query the position of an object inside my CAD drawing, the system returns a 3x4 matrix
[Rotations | Translations]
I think that the Rotations are expressed in a ZXZ fashion but for further processing I'd like to convert that rotation matrix to a XYZ notation, is this something doable?
Edit:
My object is positionned at [ 0, 0, 1000 ] the orientation given by Catia is
R = [ 1 0 0 ]
[ 0 0 1 ]
[ 0 -1 0 ]
When I try to multiply my own point [ 0, 0, 50 ] ( just an offset on the Z axis )
P1 = [ 0 ]
[ 0 ]
[ 50 ]
R*P1 = [ 0 ]
[ 50 ]
[ 0 ]
This is what lead me to believe that the rotation matrix is not XYZ with right hand notation.
Upvotes: 2
Views: 6417
Reputation: 29244
I just tested this code and it works ok. It goes through all the alternatives for angles and returns the ones closest to 0.
public class Matrix3
{
double a11,a13,a13,a21,a22,a23,a31,a32,a33;
public void GetEulerZXZDegree(out double a, out double b, out double c)
{
GetEulerZXZ(out a, out b, out c);
a*=180/Math.PI;
b*=180/Math.PI;
c*=180/Math.PI;
}
public void GetEulerZXZ(out double a, out double b, out double c)
{
// Options
double[] a_list=new double[] { Math.Atan2(-a13, a23), Math.Atan2(a13, -a23) };
double[] c_list=new double[] { Math.Atan2(a31, a32), Math.Atan2(-a31, -a32) };
double[] b_list=new double[] { Math.PI/2-Math.Asin(a33), -Math.PI/2+Math.Asin(a33) };
int min_a_index=FindMinAbsIndex(a_list);
int min_b_index=FindMinAbsIndex(b_list);
int min_c_index=FindMinAbsIndex(c_list);
a=a_list[min_a_index];
b=b_list[min_b_index];
c=c_list[min_c_index];
}
public void GetEulerZYXDegree(out double a, out double b, out double c)
{
GetEulerZYX(out a, out b, out c);
a*=180/Math.PI;
b*=180/Math.PI;
c*=180/Math.PI;
}
public void GetEulerZYX(out double a, out double b, out double c)
{
// Options
double[] a_list=new double[] { Math.Atan2(a21, a11), Math.Atan2(-a21, -a11) };
double[] c_list=new double[] { Math.Atan2(a32, a33), Math.Atan2(-a32, -a33) };
double[] b_list=new double[] { -Math.Asin(a31), Math.Asin(a31)-Math.PI };
int min_a_index=FindMinAbsIndex(a_list);
int min_b_index=FindMinAbsIndex(b_list);
int min_c_index=FindMinAbsIndex(c_list);
a=a_list[min_a_index];
b=b_list[min_b_index];
c=c_list[min_c_index];
}
// This returns the index of the smallest number
public static int FindMinAbsIndex(double[] list)
{
if(list.Length==0) return -1;
double x=Math.Abs(list[0]);
int index=0;
for(int i=1; i<list.Length; i++)
{
if(Math.Abs(list[i])<x)
{
index=i;
x=Math.Abs(list[i]);
}
}
return index;
}
}
Here is a unit test:
/// <summary>
///A test for GetEulerZXZDegree
///</summary>
[TestMethod()]
public void GetEulerZXZDegreeTest()
{
// Make matrix from three rotations
// RZ(75)*RX(22)*RZ(-12)
Matrix3 target =
Rotations.RotateZDegrees( 75)*
Rotations.RotateXDegrees( 22)*
Rotations.RotateZDegrees(-12);
//Matrix3 target=new Matrix3(
// 0.439367031912771, -0.822208517146682, 0.361842183278486,
// 0.894924870582839, 0.435556129311581, -0.0969553207969503,
// -0.0778850902285301, 0.366420540568700, 0.927183854566759);
double a;
double aExpected=75;
double b;
double bExpected=22;
double c;
double cExpected=-12;
target.GetEulerZXZDegree(out a, out b, out c);
Assert.AreEqual(aExpected, a, 1e-8);
Assert.AreEqual(bExpected, b, 1e-8);
Assert.AreEqual(cExpected, c, 1e-8);
}
Upvotes: 1
Reputation: 2672
You may think of your 3x4 transformation matrix as a set of three unit vectors that define transformed coordinate system axes (first three columns of the matrix) and an origin of that coordinate system (fourth column).
For your case the unit vectors are:
So in your transformed system, X axis is the same as original one, Y became -Z, and Z became +Y. That is actually a 90 degrees rotation around X axis (when Z turns towards Y).
X = (1, 0, 0)
Y = (0, 0, -1)
Z = (0, 1, 0)
Upvotes: 0
Reputation: 19104
Who gives matrices in ZXZ notation? Are you sure it is the format?
If it's a regular roation matrix, then you should start by taking a unit vector along one of the axes and see where the transformation brings it. It will give you two of the euler angles. To get the third, you need to consider a plane generated by two vectors.
Upvotes: 0