diff --git "a/\345\274\240\351\233\252\351\242\226\347\254\254\344\270\200\346\254\241\344\273\277\347\234\237\344\275\234\344\270\232" "b/\345\274\240\351\233\252\351\242\226\347\254\254\344\270\200\346\254\241\344\273\277\347\234\237\344\275\234\344\270\232" new file mode 100644 index 0000000000000000000000000000000000000000..dbd9a2d4c959e7edc651070a5d8609f532255b91 --- /dev/null +++ "b/\345\274\240\351\233\252\351\242\226\347\254\254\344\270\200\346\254\241\344\273\277\347\234\237\344\275\234\344\270\232" @@ -0,0 +1,117 @@ +///*********************************************************************** +/// 根据方向余弦矩阵计算欧拉角 +/// @Author Zhang Xuaying +/// @Date 2023.04.01 +/// @Input +/// @Param mtx 方向余弦矩阵 +/// @Param Angles 欧拉角 +/// @Output +///*********************************************************************** +#include "AsMtxToEuler.h" +#include "SimDoF6.h" +#include "DoF6.h" + +const double PI = 3.141592653; + + +//定义欧拉角的结构体 +struct Angles +{ + double m_Angle2, m_Angle1, m_Angle3; +}; + + +void AsMtxToEuler() +{ + printf("*****************************************************************\n"); + printf("* *\n"); + printf("* <<方向余弦矩阵转为312转序Euler角>> *\n"); + printf("* *\n"); + printf("***************************************************************\n\n"); + //输入矩阵 + cout << "请输入方向余弦矩阵"; + CMatrix mtx(3, 3);//定义一个矩阵用于存放方向余弦矩阵的数据 + CMatrix mtx_tr(3, 3);//定义一个矩阵用于存放矩方向余弦矩阵的转置 + CMatrix mtx_inv(3, 3);//定义一个矩阵用于存放方向余弦矩阵的逆 + double mtx_det;//定义一个双精度浮点型数据,矩阵用于存放方向余弦矩阵的行列式 + Angles angles; //定义一个结构体,用于储存欧拉角 + + + //输入方向余弦矩阵 + int i, j, n; + cout << "请输入方向余弦矩阵的维度: ";//测试矩阵维度是否合理 + cin >> n; + bool flag_dim = n != 3; + if (!flag_dim) + { + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + { + cout << " Matrix[" << i + 1 << "][" << j + 1 << "] : "; + double a; + cin >> a; + bool flag = ((a > 1)||(a < -1));//设置布尔类型数据测试矩阵的元素大小是否合理 + if (!flag) + { + mtx[i][j] = a; + } + else + { + cout << "请输入小于1的矩阵元素" << endl; + goto mark;//如果矩阵元素的绝对值大于1则跳出程序 + } + } + //判断是否满足方向余弦矩阵的性质(行列式为1或-1) + mtx_det = mtx.Det(); + if (abs(mtx_det) - 1 <= 0e-7 ) + { + bool singular = mtx(1, 2) > 1 - 1e-8;//判断是否出现欧拉角奇异问题 + if (!singular) + { + angles.m_Angle2 = asin(mtx(1, 2)) / PI * 180; + if (mtx(1, 0) == 0) + { + angles.m_Angle1 = 0; + } + else + { + angles.m_Angle1 = -atan2(mtx(1, 0), mtx(1, 1)) / PI * 180;//偏航 + } + + if (mtx(0, 2) == 0) + { + angles.m_Angle3 = 0; + } + else + { + angles.m_Angle3 = -atan2(mtx(0, 2), mtx(2, 2)) / PI * 180;//俯仰 + } + } + else + { + cout << "出现欧拉角数值奇异问题" << endl; + angles.m_Angle1 = 0; + angles.m_Angle2 = asin(mtx(1, 2)); + angles.m_Angle3 = atan2(mtx(2, 0), mtx(0, 0)); + } + cout << "EulerAngles result is:" << endl; + cout << "z = " << angles.m_Angle1 << endl; + cout << "x = " << angles.m_Angle2 << endl; + cout << "y = " << angles.m_Angle3 << endl << endl; + } + else + { + cout << "请输入行列式的值为1或-1的的矩阵" << endl; + goto mark;//值大于1则跳出程序 + } + + } + else + { + cout << "请输入三维矩阵" << endl; + mark: + cout << "程序失败" << endl; + } + +} +