問題描述
如何在 MATLAB 中為一組向量的旋轉設置動畫? (How do I animate the rotation of a set of vectors in MATLAB?)
我正在嘗試可視化坐標係從固定世界框架到旋轉身體框架的旋轉。我使用 DCM 旋轉了框架,現在我正在嘗試為新框架(即 3 個正交向量)從初始框架到其旋轉方向的移動設置動畫。
我想使用 quiver3 但我在繪製下一個之前,無法讓上一個箭袋將自己從情節中刪除。結果是一排箭頭緩慢地改變大小並轉動,直到它們到達最終方向。
我懷疑這是保持/保持的問題,儘管我不知道。
如果有人能幫我製作一個矢量在空間中從初始位置旋轉到最終方向的流暢動畫,我將不勝感激。
謝謝!<
參考解法
方法 1:
Actually you don't have to use the hold on/off command. Just define the axes and your view so you can watch the rotation in a comfortable way. I used your code, actually you don't need the initialisation quiver but can directly start with the loop:
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:
One approach is to remove all uses of hold
in your code. The hold
state is off
by default, so quiver
deletes the old plot and creates a new one in each iteration. This has the unwanted effect that the scale of the axes will change to accomodate the changing arrow lengths (note that although axis manual
may be used to freeze the axis scales, that only works when the hold
state is on
). To solve it you can manually set axis sizes in each iteration, after quiver
. This is the approach used in @Till's answer (which I only just saw...).
A second approach, which I think is slightly better, is the following. You create the quiver plot initially, and within the loop instead of creating a new quiver plot you simply change the data of the existing one. These data are accessed via the properties of the quiver
object.
The advantages of the second approach are that you can set axis size once at the beginning, instead of in each iteration; and you avoid deleting the quiver plot and creating a new one every time. So the code will probably be faster, and will look cleaner:
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
(by ernieTheEagle1965、Till、Luis Mendo)