【问题标题】:How do I animate the rotation of a set of vectors in MATLAB?如何在 MATLAB 中为一组向量的旋转设置动画?
【发布时间】:2021-02-05 18:47:34
【问题描述】:

我正在尝试可视化坐标系从固定世界框架到旋转身体框架的旋转。我使用 DCM 旋转了框架,现在我尝试将新框架(即 3 个正交矢量)从初始框架移动到其旋转方向。

我想使用 quiver3,但在绘制下一个 quiver 之前,我无法让前一个 quiver 将自己从绘图中删除。结果是一排箭头缓慢地改变大小并转动,直到它们到达最终方向。

我怀疑这是暂停/暂停的问题,虽然我不知道。

如果有人能帮我制作一个矢量在空间中从初始位置旋转到最终方向的流畅动画,我将不胜感激。

谢谢!

clear all;
k = [0; 0; 1;];
j = [0; 1; 0;];
i = [1; 0; 0;];
starts = zeros(3,3);
ends = [i j k];
t = linspace(0,1,100);
yaw = pi/4;
pitch = pi/4;
roll = pi/4;
quiver3(starts(1,:), starts(2,:), starts(3,:), ends(1,:), ends(2,:), ends(3,:))
hold on;
for k = 1:length(t)
    hold on;
    yawDCM = [cos(yaw*t(k)) sin(yaw*t(k)) 0; -sin(yaw*t(k)) cos(yaw*t(k)) 0; 0 0 1*t(k)];
    pitchDCM = [cos(pitch*t(k)) 0 -sin(pitch*t(k)); 0 1*t(k) 0; sin(pitch*t(k)) 0 cos(pitch*t(k));];
    rollDCM = [1*t(k) 0 0; 0 cos(roll*t(k)) sin(roll*t(k)); 0 -sin(roll*t(k)) cos(roll*t(k));];
    Q = yawDCM*pitchDCM*rollDCM;
    ends2 = Q*ends;
%     hold on;
%     plot3(ends2(1,1), ends2(1,2), ends2(1,3), '--');
%     plot3(ends2(2,1), ends2(2,2), ends2(2,3), '--');
%     plot3(ends2(3,1), ends2(3,2), ends2(3,3), '--');
%     pause(.01);
%     hold off;
    quiver3(starts(:,1), starts(:,2), starts(:,3), ends2(:,1), ends2(:,2), ends2(:,3), 0);
    pause(.1);
    hold off
end
axis equal

【问题讨论】:

  • 欢迎来到本站!

标签: matlab vector graphics matlab-figure


【解决方案1】:

实际上,您不必使用 hold on/off 命令。只需定义轴和您的视图,以便您可以舒适地观看旋转。我使用了你的代码,其实你不需要初始化箭袋,而是可以直接从循环开始:

figure(1)
xlim([-0.5 1]); ylim([-0.5 1]); zlim([-0.5 1]);
view([45 45 45])
quiver3(starts(1,:), starts(2,:), starts(3,:), ends(1,:), ends(2,:), ends(3,:))
for k = 1:length(t)
    yawDCM = [cos(yaw*t(k)) sin(yaw*t(k)) 0; -sin(yaw*t(k)) cos(yaw*t(k)) 0; 0 0 1*t(k)];
    pitchDCM = [cos(pitch*t(k)) 0 -sin(pitch*t(k)); 0 1*t(k) 0; sin(pitch*t(k)) 0 cos(pitch*t(k));];
    rollDCM = [1*t(k) 0 0; 0 cos(roll*t(k)) sin(roll*t(k)); 0 -sin(roll*t(k)) cos(roll*t(k));];
    Q = yawDCM*pitchDCM*rollDCM;
    ends2 = Q*ends;
    quiver3(starts(:,1), starts(:,2), starts(:,3), ends2(:,1), ends2(:,2), ends2(:,3), 0);
    xlim([-0.5 1]); ylim([-0.5 1]); zlim([-0.5 1]);
    view([45 45 45])
    pause(.1);    
end

【讨论】:

    【解决方案2】:

    一种方法在您的代码中删除所有使用holdhold 状态默认为off,因此quiver 删除旧图并在每次迭代中创建一个新图。这会产生不希望的效果,即轴的刻度将更改以适应不断变化的箭头长度(请注意,尽管axis manual 可用于冻结轴刻度,但仅当hold 状态为on 时才有效)。为了解决这个问题,您可以在quiver 之后在每次迭代中手动设置轴尺寸。这是@Till's answer 中使用的方法(我只是看到...)。

    第二种方法,我认为稍微好一点,如下所示。您最初创建了箭袋图,并且在循环中而不是创建新的箭袋图您只需更改现有的数据。这些数据通过quiver 对象的properties 访问。

    第二种方法的优点是您可以在开始时设置一次轴大小,而不是在每次迭代中;并且您避免每次都删除箭袋图并创建一个新图。所以代码可能会更快,并且看起来更干净

    clear
    k = [0; 0; 1;];
    j = [0; 1; 0;];
    i = [1; 0; 0;];
    starts = zeros(3,3);
    ends = [i j k];
    t = linspace(0,1,100);
    yaw = pi/4;
    pitch = pi/4;
    roll = pi/4;
    h = quiver3(starts(1,:), starts(2,:), starts(3,:), ends(1,:), ends(2,:), ends(3,:)); % create quiver object
    axis([-.5 .8 -.5 1 0 1]); % choose axis size
    view([-40 25]) % choose viewing angle
    axis manual % this freezes axis size
    for k = 1:length(t)
        yawDCM = [cos(yaw*t(k)) sin(yaw*t(k)) 0; -sin(yaw*t(k)) cos(yaw*t(k)) 0; 0 0 1*t(k)];
        pitchDCM = [cos(pitch*t(k)) 0 -sin(pitch*t(k)); 0 1*t(k) 0; sin(pitch*t(k)) 0 cos(pitch*t(k));];
        rollDCM = [1*t(k) 0 0; 0 cos(roll*t(k)) sin(roll*t(k)); 0 -sin(roll*t(k)) cos(roll*t(k));];
        Q = yawDCM*pitchDCM*rollDCM;
        ends2 = Q*ends;
        h.XData = starts(:,1); h.YData = starts(:,2); h.ZData = starts(:,2); % update quiver properties
        h.UData = ends2(:,1); h.VData = ends2(:,2); h.WData = ends2(:,3); % update quiver properties
        pause(.02);
    end
    

    【讨论】:

    • 是的,你的第二种方法肯定比我的更好,更优雅,特别是如果t 变得非常高。谢谢:)
    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    相关资源
    最近更新 更多