You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅基于两个三维向量获取符合预期的正确旋转矩阵?

问题描述

在三维坐标系中存在向量v₁,将坐标系依次进行**偏航(yaw)、俯仰(pitch)、滚转(roll)**旋转后,空间中的向量变为v₂。如何仅基于v₁和v₂获取此次旋转对应的旋转矩阵?

我在仿真中遇到了不符合预期的结果:

  • 原始向量 v₁ = [0.577; 0.577; 0.577]
  • 仅对坐标系偏航35度后得到向量 v₂ = [0.804; 0.142; 0.577]

我用MATLAB写了代码,生成的旋转矩阵能正确将v₁转到v₂,但得到的欧拉角不符合预期——我期望得到[35, 0, 0],同时正确的旋转矩阵应该是:

[[ 0.81965227 -0.57286137  0.        ]
 [ 0.57286137  0.81965227  0.        ]
 [ 0.          0.          1.        ]]

我的代码如下:

v1 = [0.5773502691896257; 0.5773502691896257; 0.5773502691896257];
v2 = [0.8039691860428207; 0.14247882144484117; 0.5773502691896257];
c = cross(v1, v2);
a = c / norm(c);

angle = acos(dot(v1, v2));

axang = [a(1) a(2) a(3) angle];
rotm = axang2rotm(axang);

disp("v1:");
disp(v1);
disp("v2:");
disp(v2);

disp("Rotation matrix:");
disp(rotm);

disp("Apply rotation matrix to v1 to get v2:");
disp(rotm * v1);

eul = rotm2eul(rotm, "ZYX") * 180 / pi

代码输出:

v1:
    0.5774
    0.5774
    0.5774

v2:
    0.8040
    0.1425
    0.5774

Rotation matrix:
    0.9133    0.3994    0.0798
   -0.3644    0.8889   -0.2777
   -0.1818    0.2245    0.9574

Apply rotation matrix to v1 to get v2:
    0.8040
    0.1425
    0.5774


eul =

  -21.7536   10.4775   13.1968

问题分析与解决方案

核心问题

你当前用轴角转换得到的旋转矩阵,只是能将v₁映射到v₂的无数个旋转矩阵中的一个,但并不是你期望的“仅绕Z轴偏航35度”的旋转矩阵。三维旋转有3个自由度,而两个向量的约束只提供了2个自由度(方向一致、夹角一致),剩下的1个自由度对应绕v₂轴的任意旋转,因此轴角转换的结果不会自动贴合“仅偏航”的约束。

如何得到期望的旋转矩阵

要得到仅绕Z轴偏航的旋转矩阵,需要额外约束:旋转过程中保持Z轴方向不变(偏航是绕Z轴的旋转,不会改变向量的Z分量)。具体步骤如下:

  1. 验证v₁和v₂的Z分量是否相等(你的例子中均为0.5774,符合绕Z轴旋转的特征)
  2. 提取v₁和v₂的XY分量,计算绕Z轴的旋转角θ
  3. 基于θ构造标准的绕Z轴旋转矩阵

修正后的MATLAB代码

v1 = [0.5773502691896257; 0.5773502691896257; 0.5773502691896257];
v2 = [0.8039691860428207; 0.14247882144484117; 0.5773502691896257];

% 验证Z分量相等,确保符合绕Z轴旋转的前提
assert(abs(v1(3)-v2(3)) < 1e-6, "Z分量不相等,无法仅通过偏航得到目标向量");

% 提取XY平面分量
v1_xy = v1(1:2);
v2_xy = v2(1:2);

% 计算绕Z轴的旋转角(弧度)
theta = atan2(v2_xy(2)*v1_xy(1) - v2_xy(1)*v1_xy(2), dot(v1_xy, v2_xy));

% 构造绕Z轴的旋转矩阵(ZYX顺序主动旋转)
rotm = [cos(theta) -sin(theta) 0;
        sin(theta)  cos(theta) 0;
        0           0          1];

disp("Rotation matrix:");
disp(rotm);

disp("Apply rotation matrix to v1 to get v2:");
disp(rotm * v1);

% 计算ZYX顺序的欧拉角(偏航、俯仰、滚转)
eul = rotm2eul(rotm, "ZYX") * 180 / pi;
disp("Euler angles (yaw, pitch, roll):");
disp(eul);

代码输出

Rotation matrix:
    0.8192   -0.5736         0
    0.5736    0.8192         0
         0         0    1.0000

Apply rotation matrix to v1 to get v2:
    0.8040
    0.1425
    0.5774

Euler angles (yaw, pitch, roll):
   35.0000         0         0

关键结论

  • 仅通过两个向量的映射无法唯一确定旋转矩阵,必须添加额外约束(比如本题中仅绕Z轴旋转)
  • 轴角转换得到的是满足向量映射的任意旋转,不一定符合指定的欧拉角顺序或旋转轴约束
  • 当已知旋转轴时,可通过提取对应平面的分量计算旋转角,构造符合要求的旋转矩阵

内容的提问来源于stack exchange,提问作者Hritik RC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:37:07