不同的几何库对于旋转方向的正负号问题的定义不尽相同。这里主要验证下Eigen
库旋转时,正负号判定的问题。
void TEST_rotation_direction_positive_negative_view_from_x_positive_to_origin()
{
Eigen::Matrix3d R;
R = Eigen::AngleAxisd(M_PI / 4, Eigen::Vector3d::UnitX());
Eigen::Vector3d input_point(0, 1, 0);
Eigen::Vector3d output_point = R * input_point;
std::cout << "output_point.y: " << output_point(1) << std::endl;
std::cout << "output_point.z: " << output_point(2) << std::endl;
if(output_point[2] > 0)
std::cout << "逆时针为正" << std::endl;
else
std::cout << "顺时针为正" << std::endl;
}
输出如下:
output_point.y: 0.707107
output_point.z: 0.707107
逆时针为正
void TEST_rotation_direction_positive_negative_view_from_y_positive_to_origin()
{
Eigen::Matrix3d R;
R = Eigen::AngleAxisd(M_PI / 4, Eigen::Vector3d::UnitY());
Eigen::Vector3d input_point(0, 0, 1);
Eigen::Vector3d output_point = R * input_point;
std::cout << "output_point.x: " << output_point(0) << std::endl;
std::cout << "output_point.y: " << output_point(2) << std::endl;
if(output_point[0] > 0)
std::cout << "逆时针为正" << std::endl;
else
std::cout << "顺时针为正" << std::endl;
}
输出如下:
output_point.x: 0.707107
output_point.y: 0.707107
逆时针为正
void TEST_rotation_direction_positive_negative_view_from_z_positive_to_origin()
{
Eigen::Matrix3d R;
R = Eigen::AngleAxisd(M_PI / 4, Eigen::Vector3d::UnitZ());
Eigen::Vector3d input_point(1.0, 0, 0);
Eigen::Vector3d output_point = R * input_point;
std::cout << "output_point.x: " << output_point(0) << std::endl;
std::cout << "output_point.y: " << output_point(1) << std::endl;
if(output_point[1] > 0)
std::cout << "逆时针为正" << std::endl;
else
std::cout << "顺时针为正" << std::endl;
}
输出如下:
output_point.x: 0.707107
output_point.y: 0.707107
逆时针为正
由任意一个轴的正方向看向坐标系的原点,逆时针为正
eulerAngles()
用于将旋转矩阵转换为欧拉角,使用时需要根据实际情况指定绕轴旋转的顺序。eulerAngles()
的函数原型如下:
Eigen::vector3d eulerAngles(Index a0, Index a1, Index a2)
,其中参数a0 a1 a2
用 0 1 2
表示旋转轴,其中0表示X轴,1表示Y轴,2表示Z轴。此外,a0 表示首先选择的轴,a1 表示其次旋转的轴,a2 表示最后旋转的轴。输出结果的顺序与轴旋转的顺序相同。
以下通过两种情况进行验证:
void TEST_x30_y45_z60()
{
double x = M_PI / 6;
double y = M_PI / 4;
double z = M_PI / 3;
Eigen::Matrix3d R;
R = Eigen::AngleAxisd(x, Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(y, Eigen::Vector3d::UnitY()) *
Eigen::AngleAxisd(z, Eigen::Vector3d::UnitZ());
auto angle = R.eulerAngles(0, 1, 2) * 180 / M_PI;
std::cout << "X = " << angle(0) << std::endl;
std::cout << "Y = " << angle(1) << std::endl;
std::cout << "Z = " << angle(2) << std::endl;
if ((std::abs(angle(0) - 30) < 0.001) &&
(std::abs(angle(1) - 45) < 0.001) &&
(std::abs(angle(2) - 60) < 0.001))
{
std::cout << "xyz" << std::endl;
}
}
输出结果如下:
X = 30
Y = 45
Z = 60
xyz
void TEST_z60_y45_x30()
{
double x = M_PI / 6;
double y = M_PI / 4;
double z = M_PI / 3;
Eigen::Matrix3d R;
R = Eigen::AngleAxisd(z, Eigen::Vector3d::UnitZ()) *
Eigen::AngleAxisd(y, Eigen::Vector3d::UnitY()) *
Eigen::AngleAxisd(x, Eigen::Vector3d::UnitX());
auto angle = R.eulerAngles(2, 1, 0) * 180 / M_PI;
std::cout << "Z = " << angle(0) << std::endl;
std::cout << "Y = " << angle(1) << std::endl;
std::cout << "Z = " << angle(2) << std::endl;
if ((std::abs(angle(0) - 60) < 0.001) &&
(std::abs(angle(1) - 45) < 0.001) &&
(std::abs(angle(2) - 30) < 0.001))
{
std::cout << "zyx" << std::endl;
}
}
输出结果如下:
Z = 60
Y = 45
Z = 30
zyx