2016-08-31 63 views
0

我試圖在Matlab中編寫一個動畫代碼,每兩秒鐘重複一次。核心動畫方案如下:Matlab - 每兩秒鐘初始化腳本

GIF image for Core animation

請多保重GIF是重複的Core Animation,原本只有一個循環。

下面是代碼:

% 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

建議:實現一個只執行一個ani的函數配對步驟(每次執行該功能時,它都會「呈現」一個幀)。然後您可以使用計時器每2秒執行一次步驟。您也可以嘗試並行計算工具箱。 – Rotem

回答

0

我創建,顯示它可以如何進行的示例。
修改你的代碼,繪製「一個動畫步驟」是太多的工作。
我決定用你的代碼來創建所有的幀(例如,目的)。
我想你會意識到,在Matlab中實現背景動畫比你想象的要難(除非我錯過了一些隱藏的Matlab特性)。
Matlab的線程支持非常有限,所以我使用了週期性定時器。

我的代碼示例執行下列操作:

  • 構建動畫 - 創建所有的動畫圖像的單元陣列。
    你應該避免它,因爲它需要很多時間(和內存)。
    我用它來代替修改代碼來繪製一個動畫圖像。
  • 設置週期爲0.2秒的週期性定時器對象(以0.2爲例)。
  • 我添加了一個循環來說明前臺處理(以sin(x)爲例)。
    注意:我在「前景處理」循環中添加了一些小暫停。
  • 定時器每0.2秒調用一次回調函數。
    在回調函數中顯示下一個動畫幀。
    該計時器用於模擬後臺執行。
    您應該使用您的「動畫步驟」功能替換imshow,該功能可以繪製框架(而不是顯示先前創建的框架)。

下面是代碼示例(帶有您修改後的代碼):

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 

示例我的意思通過「畫只是一個動畫一步」

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 
+0

Rotem真的很辛苦,謝謝。我應該怎麼做才能每2秒重複一次動畫代碼。我用描述我想要的圖形編輯問題。也許這會更清楚。逐幀編程的想法很好,但是我需要計算大量的幀,因爲我們不知道用戶何時想停止動畫。 –

+0

我並不是說你需要「計算大量的幀」。我指示你把它替換成**「只畫一個動畫步驟」**。我添加了一個例子,顯示我的意思是「繪製一個動畫步驟」**。 – Rotem