Matlab - 每两秒初始化一个脚本

时间:2016-08-31 09:00:17

标签: matlab animation

我尝试在Matlab中编写动画代码,每两秒钟重复一次。核心动画方案如下:

GIF image for Core animation

请注意gif正在重复核心动画,原来只有一个循环。

以下是代码:

    % Figure settings
h= figure(2);
set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
         'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);

%Parameters
diameter = 60; %spot çapı
RamanX = 350; %ölçüm noktssı x konumu
nOfSpots = 4; %spot sayısı
spotCount = 0; %toplam spot sayısı
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %Ölçüm sonunda verilen karar
deltaY2 = 100; % spotlar arası mesafe


x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);

for i=1:nOfSpots
    x11(i,:) = [RamanX   150*(i-1)];
    x22(i,:) = [800 50+deltaY2*(i-1)];
end

for i=1:nOfSpots/2
    x22a(2*i-1,:) = [1280 -270+250*(i-1)];
    x22a(2*i,:) = [1075 -270+250*(i-1)];
    x22b(2*i-1,:) = [1280 220+250*(i-1)];
    x22b(2*i,:) = [1075 220+250*(i-1)];
end

%Add 4 Circles to initial position
for i=1:nOfSpots
    % Drag & Drop elipsler yerleştiriliyor
    spot(i) =  imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
    spotCount = spotCount+1;
    %elips özellikleri
    setFixedAspectRatioMode(spot(spotCount), 'TRUE');
    setResizable(spot(spotCount),0);
    posSpot(spotCount,:) = getPosition(spot(i));
end

%Move Circles to posII
r = sqrt(sum(bsxfun(@minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;

for i=1:stepsize
    for j=1:nOfSpots
        setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
        posSpot(spotCount,:) = getPosition(spot(j));
    end
    pause(0.15)    
end

%Move Circles to posIII

velocity = 30;
r2a =  sqrt(sum(bsxfun(@minus,x22a,x11).^2,2));    
stepsize2a = max(ceil(r2a/velocity));
r2b =  sqrt(sum(bsxfun(@minus,x22a,x11).^2,2));    
stepsize2b = max(ceil(r2b/velocity));
% Eğer öllçüm seçimi 1 ise taşı
for i=1:nOfSpots
    if(Choice(i))
        xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
        ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
    else
        xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
        ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
    end
end
stepsize2 = max([stepsize2a stepsize2b]);

% Eğer ölçüm seçimi 0 ise taşı
for i=1:stepsize2
    for j=1:nOfSpots
        if(Choice(j))
            setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
            posSpot(spotCount,:) = getPosition(spot(j));
        end
    end
    pause(0.15)
end

for i=1:stepsize2
    for j=1:nOfSpots
        if(~Choice(j))
            setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
            posSpot(spotCount,:) = getPosition(spot(j));
        end
    end
    pause(0.15)
end

if(spotCount > 0)
    for i=1:4
        delete(spot(i))
    end
end

执行此操作的代码是脚本而非函数,例如“animation.m”。现在我尝试每2秒重复一次这段代码。我尝试使用带有tic-toc命令的循环,但循环在完成“animation.m”之前不会进入其他循环。我需要在后台运行它。

我的一位朋友建议我使用触发器。但是,老实说,即使我将其功能化,我也无法对我的代码应用触发器命令。

任何帮助?

编辑: 问题的图形流程图如下:

The graphical flow chart of the problem

1 个答案:

答案 0 :(得分:0)

我创建了一个示例,说明如何完成。
修改你的代码,只绘制一个动画步骤&#34;工作太多了。
我决定使用你的代码从提前创建所有帧(例如目的) 我想你会意识到,在Matlab中实现背景动画比你想象的要困难(除非我错过了一些隐藏的Matlab功能)。
Matlab的线程支持非常有限,因此我使用了定期计时器。

我的代码示例执行以下操作:

  • 构建动画 - 创建所有动画图像的单元格数组 你应该避免它,因为它需要很长时间(和记忆)。
    我使用它而不是修改你的代码来绘制一个动画图像。
  • 设置周期性计时器对象,周期为0.2秒(以0.2为例)。
  • 我添加了一个循环来说明前景处理(以sin(x)为例) 注意:我在&#34;前台处理&#34;中添加了小暂停。环。
  • 计时器每0.2秒调用一次回调函数 在回调函数中,显示下一个动画帧 计时器用于模拟后台执行 您应该使用&#34;动画步骤替换imshow&#34;功能,绘制框架(而不是显示从提前创建的框架)。

以下是代码示例(包含修改后的代码):

function TimerAnimation()

    %Build set of images for animation.
    [h_figure, Frames] = BuildAnimation();

    t = timer;
    t.TimerFcn = @timerFcn_Callback; %Set timer callback function
    t.ExecutionMode = 'fixedRate';   %Set mode to "singleShot" - execute TimerFcn only once.
    t.StartDelay = 0.1;              %Wait 0.1 second from start(t) to executing timerFcn_Callback.
    t.Period = 0.2;                  %Set period to 0.2 seconds.

    %Turn on figure visibility
    set(h_figure, 'Visible', 'on');
    frame_counter = 1;

    start(t) %Start timer;

    %Do some other job...
    %The animation is executed in the background (kind of in the background).
    for x = 1:20000
        y = sin(x/10000); %Calculate somthing...
        if (mod(x, 100) == 0)
            disp(['sin(', num2str(x/10000), ') = ', num2str(y)]); %Display somthing...
        end

        if (~isvalid(h_figure))
            %Break loop if user closed the animation figure.
            break;
        end

        %Must insert pause to "tight loop", allowing animation to run.
        pause(0.01);
    end

    stop(t)     %Stop timer;
    delete(t);  %Delete timer object.
    if (~isvalid(h_figure))
        close(h_figure);
    end


    %Timer function is executed every period of 0.2 seconds.
    function timerFcn_Callback(mTimer, ~)
        %Increse animation frame counter.
        %figure(h_figure); %Set fo h_figure to be active figure.

        h_axes = get(h_figure, 'CurrentAxes'); %Get axes of h_figure
        imshow(Frames{frame_counter}, 'Parent', h_axes); %Display frame number frame_counter.
        drawnow; %Force refresh.
        frame_counter = mod(frame_counter, length(Frames)) + 1; %Advance to next frame (cyclically).
    end
end


function [h, Frames] = BuildAnimation()
%Build set of images for animation.
%h - return handle to figure
%Frames - return cell array of animation images.

counter = 1;

% Figure settings
%h = figure(2);

%Create invisible figure.
h = figure('Visible', 'off');

set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
         'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);

%Parameters
diameter = 60; %spot ?ap?
RamanX = 350; %?l??m noktss? x konumu
nOfSpots = 4; %spot say?s?
spotCount = 0; %toplam spot say?s?
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %?l??m sonunda verilen karar
deltaY2 = 100; % spotlar aras? mesafe


x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);

for i=1:nOfSpots
    x11(i,:) = [RamanX   150*(i-1)];
    x22(i,:) = [800 50+deltaY2*(i-1)];
end

for i=1:nOfSpots/2
    x22a(2*i-1,:) = [1280 -270+250*(i-1)];
    x22a(2*i,:) = [1075 -270+250*(i-1)];
    x22b(2*i-1,:) = [1280 220+250*(i-1)];
    x22b(2*i,:) = [1075 220+250*(i-1)];
end

%Add 4 Circles to initial position
for i=1:nOfSpots
    % Drag & Drop elipsler yerle?tiriliyor
    spot(i) =  imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
    spotCount = spotCount+1;
    %elips ?zellikleri
    setFixedAspectRatioMode(spot(spotCount), 'TRUE');
    setResizable(spot(spotCount),0);
    posSpot(spotCount,:) = getPosition(spot(i));
end

%Move Circles to posII
r = sqrt(sum(bsxfun(@minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;

for i=1:stepsize
    for j=1:nOfSpots
        setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
        posSpot(spotCount,:) = getPosition(spot(j));
    end
    %pause(0.15)

    %Get frame, convert frame to image, and store image in Frames
    Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end

%Move Circles to posIII

velocity = 30;
r2a =  sqrt(sum(bsxfun(@minus,x22a,x11).^2,2));    
stepsize2a = max(ceil(r2a/velocity));
r2b =  sqrt(sum(bsxfun(@minus,x22a,x11).^2,2));    
stepsize2b = max(ceil(r2b/velocity));
% E?er ?ll??m se?imi 1 ise ta??
for i=1:nOfSpots
    if(Choice(i))
        xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
        ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
    else
        xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
        ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
    end
end
stepsize2 = max([stepsize2a stepsize2b]);

% E?er ?l??m se?imi 0 ise ta??
for i=1:stepsize2
    for j=1:nOfSpots
        if(Choice(j))
            setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
            posSpot(spotCount,:) = getPosition(spot(j));
        end
    end
%   pause(0.15)

    %Get frame, convert frame to image, and store image in Frames
    Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end

for i=1:stepsize2
    for j=1:nOfSpots
        if(~Choice(j))
            setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
            posSpot(spotCount,:) = getPosition(spot(j));
        end
    end

%   pause(0.15)
    %Get frame, convert frame to image, and store image in Frames
    Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end

if(spotCount > 0)
    for i=1:4
        delete(spot(i))
    end
end

imshow(Frames{1})
end

我的意思是&#34;仅绘制一个动画步骤&#34;

function TimerAnimation2()
    %Initiazlie animation.
    param = InitAnimation();

    %Same code as in previous example.
    t = timer;t.TimerFcn = @timerFcn_Callback;t.ExecutionMode = 'fixedRate';t.StartDelay = 0.1;t.Period = 0.2;start(t)
    for x = 1:20000;if (~isvalid(param.h)), break;end;pause(0.01);end 
    stop(t);delete(t);if (isvalid(param.h)), close(param.h);end

    %Timer function is executed every period of 0.2 seconds.
    function timerFcn_Callback(mTimer, ~)
        %Animation single step
        param = StepAnimation(param);
    end
end


function param = InitAnimation()
    h = figure;

    set(h, 'Position', [100 50 1200 750]);set(h,'Toolbar','None','Menubar','None');set(h,'Name','Animation');set(gcf,'doublebuffer','off');
    set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual', 'climmode','manual','alimmode','manual');
    xlim([-200 1350]);ylim([-250 800]);set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);

    %Initialize param struct (param struct keeps animation parameters). 
    param.h = h;
    param.x = 10;
    param.y = 10;

    %Draw rectangle in position x, y
    h_axes = get(param.h, 'CurrentAxes');
    rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes);
end


%Example fo single animation step
%Get exsiting animation param as input, and retuen updated param as output.
function param = StepAnimation(param)
    h_axes = get(param.h, 'CurrentAxes');

    %Update param (to be used in next StepAnimation).
    param.x = param.x + 10;
    param.y = param.y + 10;

    if (param.x > 500), param.x = 10;end
    if (param.y > 500), param.y = 10;end

    %Draw rectangle in position x, y
    rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes)
    drawnow; %Force refresh.
end