首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >子对象围绕父轴旋转,而不是自己的

子对象围绕父轴旋转,而不是自己的
EN

Stack Overflow用户
提问于 2018-10-15 19:13:30
回答 1查看 217关注 0票数 0

所以,我有一个模拟汽车的C ++项目。我的程序是工作在2D(只在XY平面),它提供了由一个玫瑰花袋给出的里程数据,给他的位置在XYplane中取决于世界的起源。在2D中一切都很好。

但当我在3D模式下时,这意味着我可以绕几个轴旋转我的车,而不仅仅是Z轴。我意识到我的车正在围绕“世界”轴的轴旋转,当我想让它们绕着我的车辆轴旋转时。

我能让我的车绕着自己的轴旋转吗?数学会是怎样的呢?

下面的两个旋转是围绕世界轴进行的。

下面是我的一段代码来说明:

代码语言:javascript
复制
void NodeImpl::callback_odometry(motion_common_msg::Odometry input_msg)
{
  //Getting Direction3D

//---
    frame_id = input_msg.header.frame_id;
    stamp = input_msg.header.stamp;

    transform_from_odometry.setOrigin(new_position_3D);

    tf::Quaternion q;
    q.setRPY(0.0, 0.0, 0.0);
    transform_from_odometry.setRotation(q);

    if(input_msg.pos_x >= 5.0)
    {
        double cos90 = 0;
        double sin90 = 1;

        tf::Matrix3x3 Rz90;
        tf::Matrix3x3 Ry90;

        Rz90.setValue(cos90, - sin90, 0, sin90, cos90, 0, 0, 0, 1);
        Ry90.setValue(cos90, 0, sin90, 0, 1, 0, -sin90, 0, cos90);

        tf::Quaternion qz90;
        tf::Quaternion qy90;

        Rz90.getRotation(qz90);
        Ry90.getRotation(qy90);

        qz90.normalize();
        qy90.normalize();

        tf::Transform tf_new_rot;

        tf_new_rot.setRotation(qz90);

        transform_from_odometry.setRotation(qy90);

        transform_from_odometry.mult (transform_from_odometry, tf_new_rot);
    }

    broadcast();
}

void NodeImpl::broadcast()
{
     static tf::TransformBroadcaster br;
     br.sendTransform(tf::StampedTransform(transform_from_odometry, stamp, frame_id, "ego_vehicle_rear_axis"));
}
EN

回答 1

Stack Overflow用户

发布于 2018-10-15 20:33:28

我不确定您使用的是哪个库,因此我将尝试就此给出一些一般性的建议。

全局与局部旋转只是矩阵乘法顺序的问题。假设R是最终的旋转矩阵。当您使用以下顺序R=X*Y*Z乘以X、Y和Z矩阵时,这将为您提供全局旋转,而R=Z*Y*X将为您提供局部旋转

上述方法的问题在于,它将局部旋转的自由度限制为特定的Z-Y-X阶。例如,如果要旋转,首先在x轴上旋转,然后在y轴上旋转,然后在z轴上旋转,上述方法就可以很好地工作。任何其他的,都不会给你想要的结果。您必须更改矩阵乘法的顺序。

如果你想绕一个轴旋转,比如说y轴,它是你的物体的局部,那么你需要知道这个轴的位置。您需要在每次变换后保留当前轴的引用,然后使用Rotation matrix from axis and angle围绕当前局部y轴旋转。

代码语言:javascript
复制
/* from the wiki link above */    
Mat3 Axis_Matrix(float angle_, const Vec3 &axis_)
    {
        return Mat3{ cos(angle_)+pow(axis_.x,2)*(1.0-cos(angle_))              , (axis_.x*axis_.y*(1.0-cos(angle_)))-(axis_.z*sin(angle_)) , (axis_.x*axis_.z*(1.0-cos(angle_)))+(axis_.y*sin(angle_)),
                     (axis_.y*axis_.x*(1.0-cos(angle_)))+(axis_.z*sin(angle_)) , cos(angle_)+pow(axis_.y,2)*(1.0 - cos(angle_))            , (axis_.y*axis_.z*(1.0-cos(angle_)))-(axis_.x*sin(angle_)),
                     (axis_.z*axis_.x*(1.0-cos(angle_)))-(axis_.y*sin(angle_)) , (axis_.z*axis_.y*(1.0-cos(angle_)))+(axis_.x*sin(angle_)) , cos(angle_)+pow(axis_.z,2)*(1.0 - cos(angle_)) };
    }

基本上,您可以创建自己的结构来完成所有这些任务:

代码语言:javascript
复制
struct CoordinateSystem
{
    Vec3 current_x_axis;
    Vec3 current_y_axis;
    Vec3 current_z_axis;

    Mat3 local;

    void setRotationX(float angle_)
    {
        local *= Axis_Matrix(angle_, current_x_axis);
        update();
    }

    void setRotationY(float angle_)
    {
        local *= Axis_Matrix(angle_, current_y_axis);
        update();
    }

    void setRotationZ(float angle_)
    {
        local *= Axis_Matrix(angle_, current_z_axis);
        update();
    }

    void update()
    {
        current_x_axis = {-1.f, 0.f, 0.f} * local;
        current_y_axis = { 0.f, 1.f, 0.f} * local;
        current_z_axis = { 0.f, 0.f,-1.f} * local;
    }
};

然后你可以直接说:

代码语言:javascript
复制
setRotationX(45);
setRotationZ(10);
setRotationY(62);
setRotationX(34);
setRotationY(81);

所有的旋转对于你的物体来说都是局部的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52815475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档