• 【Eigen】旋转方向及eulerAngles函数参数说明


    1. 旋转方向

    不同的几何库对于旋转方向的正负号问题的定义不尽相同。这里主要验证下Eigen库旋转时,正负号判定的问题。

    1.1 绕X轴旋转一个正角度

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出如下:

    output_point.y: 0.707107
    output_point.z: 0.707107
    逆时针为正

    1.2 绕Y轴旋转一个正角度

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出如下:

    output_point.x: 0.707107
    output_point.y: 0.707107
    逆时针为正

    1.3 绕Z轴旋转一个正角度

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    输出如下:

    output_point.x: 0.707107
    output_point.y: 0.707107
    逆时针为正

    1.4 结果

    由任意一个轴的正方向看向坐标系的原点,逆时针为正

    2. eulerAngles函数参数说明

    eulerAngles()用于将旋转矩阵转换为欧拉角,使用时需要根据实际情况指定绕轴旋转的顺序。eulerAngles()的函数原型如下:
    Eigen::vector3d eulerAngles(Index a0, Index a1, Index a2),其中参数a0 a1 a20 1 2表示旋转轴,其中0表示X轴,1表示Y轴,2表示Z轴。此外,a0 表示首先选择的轴,a1 表示其次旋转的轴,a2 表示最后旋转的轴。输出结果的顺序与轴旋转的顺序相同。
    以下通过两种情况进行验证:

    2.1 先绕X轴旋转,其次绕Y轴旋转,最后绕Z轴旋转

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    输出结果如下:

    X = 30
    Y = 45
    Z = 60
    xyz

    2.2 先绕Z轴旋转,其次绕Y轴旋转,最后绕X轴旋转

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    输出结果如下:

    Z = 60
    Y = 45
    Z = 30
    zyx

  • 相关阅读:
    深度学习_6_实战_点集最优直线解_代码解析
    一键编译+执行c语言小Demo
    MySQL报错:json_contains: “The document is empty.“ at position 0.
    【Tools】i1Profiler1.7安装教程详解
    Linux 中如何修改终端提示符颜色?
    【无标题】
    【cmake】彻底弄懂cmake中的可见性/传递性 INTEFACE 问题
    [HNCTF]Web详解_原创
    [Windows驱动开发] BlackBone介绍
    二维矩阵的DFS算法框架
  • 原文地址:https://blog.csdn.net/zhy29563/article/details/126147091