Как повторить вращение из Scipy в C (собственном или Qt)

#c #qt #scipy #eigen

#c #qt #scipy #eigen

Вопрос:

У меня есть вращение, выполненное с помощью Scipy, я хотел бы повторить его в C , используя библиотеку Qt (или Eigen в качестве последнего средства). Как это можно сделать? Я пытался использовать 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])
  

Ответ №1:

Вы можете использовать собственный и легко создавать объекты вращения из углов Эйлера (см. https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#TutorialGeoEulerAngles ). Однако внутренние / внешние системы должны обрабатываться вручную и требуют немного больше усилий.

Использование C 11 и разработка / мастер ветви собственного:

 #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