Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何将ZXZ旋转矩阵转换为欧拉角?_.net_Math_3d_Catia_Euler Angles - Fatal编程技术网

.net 如何将ZXZ旋转矩阵转换为欧拉角?

.net 如何将ZXZ旋转矩阵转换为欧拉角?,.net,math,3d,catia,euler-angles,.net,Math,3d,Catia,Euler Angles,我正在使用Catia软件。当我查询CAD图形中对象的位置时,系统返回一个3x4矩阵 [旋转|平移] 我认为旋转是以ZXZ方式表示的,但为了进一步处理,我想将旋转矩阵转换为XYZ表示法,这是可行的吗 编辑: 我的对象被定位在[0,0,1000] Catia给出的方向是 R = [ 1 0 0 ] [ 0 0 1 ] [ 0 -1 0 ] 当我尝试乘以我自己的点[0,0,50](只是Z轴上的偏移量) 这就是为什么我相信旋转矩阵不是用右手符号表示的XYZ。恐怕你不得

我正在使用Catia软件。当我查询CAD图形中对象的位置时,系统返回一个3x4矩阵

[旋转|平移]

我认为旋转是以ZXZ方式表示的,但为了进一步处理,我想将旋转矩阵转换为XYZ表示法,这是可行的吗

编辑:

我的对象被定位在[0,0,1000] Catia给出的方向是

R = [ 1  0  0 ]  
    [ 0  0  1 ]  
    [ 0 -1  0 ]
当我尝试乘以我自己的点[0,0,50](只是Z轴上的偏移量)


这就是为什么我相信旋转矩阵不是用右手符号表示的XYZ。

恐怕你不得不这么做。

谁给出了用ZXZ符号表示的矩阵?你确定这是格式吗


如果它是一个规则的旋转矩阵,那么你应该从沿着其中一个轴取一个单位向量开始,看看变换会把它带到哪里。它会给你两个欧拉角。为了得到第三,你需要考虑一个由两个矢量生成的平面。

< P>你可以把你的3x4变换矩阵看作一组三个单位向量,它们定义了变换坐标系轴(矩阵的前三列)和坐标系的原点(第四列)。 对于您的情况,单位向量为:

X=(1,0,0)
Y=(0,0,-1)
Z=(0,1,0)

因此,在您的转换系统中,X轴与原始系统相同,Y变成-Z,Z变成+Y。这实际上是绕X轴旋转90度(当Z转向Y时)。

我刚刚测试了此代码,它工作正常。它遍历所有角度的备选方案,并返回最接近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;
    }
}
公共类矩阵3
{
双a11、a13、a13、a21、a22、a23、a31、a32、a33;
public void GetEulerZXZDegree(输出双a、输出双b、输出双c)
{
GetEulerZXZ(输出a、输出b、输出c);
a*=180/Math.PI;
b*=180/Math.PI;
c*=180/Math.PI;
}
public void GetEulerZXZ(输出双a、输出双b、输出双c)
{
//选择权
double[]a_list=newdouble[]{Math.Atan2(-a13,a23),Math.Atan2(a13,-a23)};
double[]c_list=newdouble[]{Math.Atan2(a31,a32),Math.Atan2(-a31,-a32)};
double[]b_list=newdouble[]{Math.PI/2-Math.Asin(a33),-Math.PI/2+Math.Asin(a33)};
int min_a_index=FindMinAbsIndex(a_列表);
int min_b_index=FindMinAbsIndex(b_列表);
int min_c_index=FindMinAbsIndex(c_列表);
a=列表[最小索引];
b=b_列表[最小b_索引];
c=c_列表[最小c_索引];
}
public void GetEulerZYXDegree(输出双a、输出双b、输出双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)
{
//选择权
double[]a_list=newdouble[]{Math.Atan2(a21,a11),Math.Atan2(-a21,-a11)};
double[]c_list=newdouble[]{Math.Atan2(a32,a33),Math.Atan2(-a32,-a33)};
double[]b_list=newdouble[]{-Math.Asin(a31),Math.Asin(a31)-Math.PI};
int min_a_index=FindMinAbsIndex(a_列表);
int min_b_index=FindMinAbsIndex(b_列表);
int min_c_index=FindMinAbsIndex(c_列表);
a=列表[最小索引];
b=b_列表[最小b_索引];
c=c_列表[最小c_索引];
}
//这将返回最小数字的索引
公共静态int FindMinAbsIndex(双[]列表)
{
if(list.Length==0)返回-1;
double x=Math.Abs(列表[0]);
int指数=0;

对于(int i=1;我对该如何进行有什么想法?鉴于这些信息,这并不容易。欧拉角有许多约定,应该提供一些有用的读数。它可能是这样设置的
RecurDyn
Multibdoy dynamics软件在
ZXZ
ZYX
中定义车身方向。
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;
    }
}
    /// <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);
    }