改变对象在八度/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