改变对象在八度/matlab 中完成旋转所需的时间长度/持续时间
Changing length of time / duration that an object takes to complete rotations in octave / matlab
我可以创建一个旋转球体,但如何让它在特定时间内完成 2 次旋转、3.5 次旋转或 x 次旋转,例如 3 秒、25.4 秒或 x 秒?
代码如下:
% Using rotate
clear all,clf reset,tic,clc, close all
figure
[x,y,z] = sphere(270);
s = surf(x,y,z,z,'EdgeColor','none');
axis vis3d
for ang = 1:360
rotate(s,[1,1,1],1)
str_1=strcat('Angle= ', sprintf('%02d',(ang)),'---------','Time in Seconds= ', sprintf('%02d',(toc)));
title({str_1});
xlabel('X-axis')
ylabel('Y-axis')
zlabel('Z-axis')
drawnow
end
Ps:我使用的是 Octave 5.1,它类似于 Matlab
使用 timer
如评论中所述,在 MATLAB 中对时序进行某种形式控制的唯一方法是使用它们的 timer
class。即使是有限的,Mathworks 也明确表示您不能期望毫秒以下的精度。
以下代码接近您的要求。它创建了一个定时器,每 period
触发一次并执行一个函数(这将旋转球体)。
诀窍是定义 period
(在代码中称为 TimeIncrement
)和 angular 旋转步骤,以便运动流畅并在目标时间内实现。
即使有计时器,尤其是对于低目标时间,它也不会精确到毫秒。我设置了一个minTimeIncrement
(基于我的机器),用于放宽旋转次数(增加angular步长)以防TimeIncrement
不足以渲染一次旋转。您可能需要针对自己的机器进行调整。
%% Create and display the sphere
clear all,clf reset,clc, close all
figure
[x,y,z] = sphere(270) ;
s = surf(x,y,z,z,'EdgeColor','none');
axis vis3d
xlabel('X-axis')
ylabel('Y-axis')
zlabel('Z-axis')
%% Parameters
minTimeIncrement = 0.040 ; % I worked that out on my machine.
% You may have to adjust for your
TotalRotationTime = 3.5 ; % in second
Nangles = 360 ; % number of angle rotations to complete a full turn
TimeIncrement = TotalRotationTime / Nangles ; % Time step between each rotation
AngularIncrement = 360 / Nangles ; % angle to rotate at each iteration
% Here we make sure to respect the timing. If the number of rotation
% increment does not fit into the total time allowed, the rotation increments
% are extended so they will be less of them.
if TimeIncrement < minTimeIncrement
warning('Period too small, the angle increment will be adjusted')
TimeIncrement = minTimeIncrement ;
Nangles = TotalRotationTime / TimeIncrement ;
AngularIncrement = 360 / Nangles ; % angle to rotate at each iteration
end
%% Create the timer and start it
t = timer ;
t.ExecutionMode = 'fixedRate' ;
t.Period = TimeIncrement ;
t.TimerFcn = @(htimer,evt) UpdateSphere(htimer,evt,s,AngularIncrement) ;
t.StopFcn = 'delete(t)' ; % for self cleanup
start(t) ;
编辑: 抱歉刚刚发现我忘记了 post 回调函数的代码。 UpdateSphere.m
的代码:
function UpdateSphere( ht , evt , s , ang_increment )
%UpdateSphere Rotate the sphere and update the title display
%% Define a few persistent variables
persistent currentAngle ;
persistent StartTime ;
%% Initialise or update persistent variables
if isempty(currentAngle)
currentAngle = 0 + ang_increment ;
% else
% currentAngle = currentAngle + ang_increment ;
end
if isempty(StartTime)
StartTime = tic ;
end
%% do the rotation
% To insure we will not go over 360 degrees
ang_increment = min(ang_increment , 360 - currentAngle) ;
currentAngle = currentAngle + ang_increment ;
rotate(s,[1,1,1],ang_increment)
strTitle = sprintf('Angle = %5.1f ° / Time = %7.3f s',currentAngle,toc(StartTime)) ;
title(strTitle);
drawnow
%% Stop the timer and reset counter if we reached a full rotation
if currentAngle >= 360
currentAngle = 0 ;
StartTime = [] ;
stop(ht) ;
end
end
我可以创建一个旋转球体,但如何让它在特定时间内完成 2 次旋转、3.5 次旋转或 x 次旋转,例如 3 秒、25.4 秒或 x 秒?
代码如下:
% Using rotate
clear all,clf reset,tic,clc, close all
figure
[x,y,z] = sphere(270);
s = surf(x,y,z,z,'EdgeColor','none');
axis vis3d
for ang = 1:360
rotate(s,[1,1,1],1)
str_1=strcat('Angle= ', sprintf('%02d',(ang)),'---------','Time in Seconds= ', sprintf('%02d',(toc)));
title({str_1});
xlabel('X-axis')
ylabel('Y-axis')
zlabel('Z-axis')
drawnow
end
Ps:我使用的是 Octave 5.1,它类似于 Matlab
使用 timer
如评论中所述,在 MATLAB 中对时序进行某种形式控制的唯一方法是使用它们的 timer
class。即使是有限的,Mathworks 也明确表示您不能期望毫秒以下的精度。
以下代码接近您的要求。它创建了一个定时器,每 period
触发一次并执行一个函数(这将旋转球体)。
诀窍是定义 period
(在代码中称为 TimeIncrement
)和 angular 旋转步骤,以便运动流畅并在目标时间内实现。
即使有计时器,尤其是对于低目标时间,它也不会精确到毫秒。我设置了一个minTimeIncrement
(基于我的机器),用于放宽旋转次数(增加angular步长)以防TimeIncrement
不足以渲染一次旋转。您可能需要针对自己的机器进行调整。
%% Create and display the sphere
clear all,clf reset,clc, close all
figure
[x,y,z] = sphere(270) ;
s = surf(x,y,z,z,'EdgeColor','none');
axis vis3d
xlabel('X-axis')
ylabel('Y-axis')
zlabel('Z-axis')
%% Parameters
minTimeIncrement = 0.040 ; % I worked that out on my machine.
% You may have to adjust for your
TotalRotationTime = 3.5 ; % in second
Nangles = 360 ; % number of angle rotations to complete a full turn
TimeIncrement = TotalRotationTime / Nangles ; % Time step between each rotation
AngularIncrement = 360 / Nangles ; % angle to rotate at each iteration
% Here we make sure to respect the timing. If the number of rotation
% increment does not fit into the total time allowed, the rotation increments
% are extended so they will be less of them.
if TimeIncrement < minTimeIncrement
warning('Period too small, the angle increment will be adjusted')
TimeIncrement = minTimeIncrement ;
Nangles = TotalRotationTime / TimeIncrement ;
AngularIncrement = 360 / Nangles ; % angle to rotate at each iteration
end
%% Create the timer and start it
t = timer ;
t.ExecutionMode = 'fixedRate' ;
t.Period = TimeIncrement ;
t.TimerFcn = @(htimer,evt) UpdateSphere(htimer,evt,s,AngularIncrement) ;
t.StopFcn = 'delete(t)' ; % for self cleanup
start(t) ;
编辑: 抱歉刚刚发现我忘记了 post 回调函数的代码。 UpdateSphere.m
的代码:
function UpdateSphere( ht , evt , s , ang_increment )
%UpdateSphere Rotate the sphere and update the title display
%% Define a few persistent variables
persistent currentAngle ;
persistent StartTime ;
%% Initialise or update persistent variables
if isempty(currentAngle)
currentAngle = 0 + ang_increment ;
% else
% currentAngle = currentAngle + ang_increment ;
end
if isempty(StartTime)
StartTime = tic ;
end
%% do the rotation
% To insure we will not go over 360 degrees
ang_increment = min(ang_increment , 360 - currentAngle) ;
currentAngle = currentAngle + ang_increment ;
rotate(s,[1,1,1],ang_increment)
strTitle = sprintf('Angle = %5.1f ° / Time = %7.3f s',currentAngle,toc(StartTime)) ;
title(strTitle);
drawnow
%% Stop the timer and reset counter if we reached a full rotation
if currentAngle >= 360
currentAngle = 0 ;
StartTime = [] ;
stop(ht) ;
end
end