如何在 C++(Eigen 或 Qt)中从 Scipy 重复旋转
How to repeat rotation from Scipy in C ++ (Eigen or Qt)
我用 Scipy 完成了轮换,我想使用 Qt 库(或 Eigen 作为最后的手段)在 C++ 中复制它。如何才能做到这一点?我尝试使用 QQuaternion::fromEulerAngles,但输出的欧拉角完全不同。你能告诉我如何重复这种旋转组合吗?
from scipy.spatial.transform import Rotation as R
r = R.from_euler('xyz', [84.8715505575325, -18.6072424802551, 106.28342910934], degrees=True)
print(r.as_matrix().transpose())
>>array([[-0.26573263, 0.90971132, 0.31907911],
[ 0.003305 , -0.33011727, 0.94393414],
[ 0.9640411 , 0.25188866, 0.08471633]])
r2 = R.from_euler('XYZ', [90, 180, 90], degrees=True)
r3 = r2 * r
print(r3.as_euler('xyz', degrees=True))
>> array([ 0.19642533, 15.41049032, 19.32819967])
您可以使用 Eigen 并从欧拉角轻松创建旋转对象(参见 https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#TutorialGeoEulerAngles)。但是,intrinsic/extrinsic 系统必须手动处理,需要更多的努力。
使用 C++11 和 development/master Eigen 分支:
#define _USE_MATH_DEFINES
#include "Eigen/Core"
#include "Eigen/Geometry"
#include <iostream>
#include <math.h>
long double operator"" _deg(long double x )
{
return M_PI * x / 180;
}
int main()
{
std::cout.precision(8);
Eigen::Quaterniond r, r2, r3;
// 'xyz' - extrinsic rotation -> z*y*x
r = Eigen::AngleAxisd(106.28342910934_deg, Eigen::Vector3d::UnitZ())
* Eigen::AngleAxisd(-18.6072424802551_deg, Eigen::Vector3d::UnitY())
* Eigen::AngleAxisd(84.8715505575325_deg, Eigen::Vector3d::UnitX());
std::cout << r.matrix().transpose() << std::endl << std::endl;
// 'XYZ' - intrinsic rotation -> x*y*z
r2 = Eigen::AngleAxisd(90.0_deg, Eigen::Vector3d::UnitX())
* Eigen::AngleAxisd(180.0_deg, Eigen::Vector3d::UnitY())
* Eigen::AngleAxisd(90.0_deg, Eigen::Vector3d::UnitZ());
r3 = r2 * r;
// 'xyz' - extrinsic rotation -> z,y,x (reversed to obtain x,y,z)
std::cout << (r3.matrix().eulerAngles(2,1,0).reverse() / M_PI) * 180 << std::endl;
return 1;
}
输出:
-0.26573263 0.90971132 0.31907911
0.0033050049 -0.33011727 0.94393414
0.9640411 0.25188866 0.08471633
0.19642533
15.41049
19.3282
我用 Scipy 完成了轮换,我想使用 Qt 库(或 Eigen 作为最后的手段)在 C++ 中复制它。如何才能做到这一点?我尝试使用 QQuaternion::fromEulerAngles,但输出的欧拉角完全不同。你能告诉我如何重复这种旋转组合吗?
from scipy.spatial.transform import Rotation as R
r = R.from_euler('xyz', [84.8715505575325, -18.6072424802551, 106.28342910934], degrees=True)
print(r.as_matrix().transpose())
>>array([[-0.26573263, 0.90971132, 0.31907911],
[ 0.003305 , -0.33011727, 0.94393414],
[ 0.9640411 , 0.25188866, 0.08471633]])
r2 = R.from_euler('XYZ', [90, 180, 90], degrees=True)
r3 = r2 * r
print(r3.as_euler('xyz', degrees=True))
>> array([ 0.19642533, 15.41049032, 19.32819967])
您可以使用 Eigen 并从欧拉角轻松创建旋转对象(参见 https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#TutorialGeoEulerAngles)。但是,intrinsic/extrinsic 系统必须手动处理,需要更多的努力。
使用 C++11 和 development/master Eigen 分支:
#define _USE_MATH_DEFINES
#include "Eigen/Core"
#include "Eigen/Geometry"
#include <iostream>
#include <math.h>
long double operator"" _deg(long double x )
{
return M_PI * x / 180;
}
int main()
{
std::cout.precision(8);
Eigen::Quaterniond r, r2, r3;
// 'xyz' - extrinsic rotation -> z*y*x
r = Eigen::AngleAxisd(106.28342910934_deg, Eigen::Vector3d::UnitZ())
* Eigen::AngleAxisd(-18.6072424802551_deg, Eigen::Vector3d::UnitY())
* Eigen::AngleAxisd(84.8715505575325_deg, Eigen::Vector3d::UnitX());
std::cout << r.matrix().transpose() << std::endl << std::endl;
// 'XYZ' - intrinsic rotation -> x*y*z
r2 = Eigen::AngleAxisd(90.0_deg, Eigen::Vector3d::UnitX())
* Eigen::AngleAxisd(180.0_deg, Eigen::Vector3d::UnitY())
* Eigen::AngleAxisd(90.0_deg, Eigen::Vector3d::UnitZ());
r3 = r2 * r;
// 'xyz' - extrinsic rotation -> z,y,x (reversed to obtain x,y,z)
std::cout << (r3.matrix().eulerAngles(2,1,0).reverse() / M_PI) * 180 << std::endl;
return 1;
}
输出:
-0.26573263 0.90971132 0.31907911
0.0033050049 -0.33011727 0.94393414
0.9640411 0.25188866 0.08471633
0.19642533
15.41049
19.3282