2016-08-31 9 views
0

2秒ごとに繰り返すMatlabにアニメーションコードを書き込もうとしました。コアアニメーションスキームは以下の通りです:Matlab - 2秒ごとにスクリプトを初期化する

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

おすすめ:1つだけのアニメーションを実行する関数を実装する(関数を実行するたびに、1つのフレームをレンダリングします)。その後、タイマーを使用して2秒ごとにステップを実行できます。 Parallel Computing Toolboxを試すこともできます。 – Rotem

答えて

0

私はそれを行うことができる方法を示す例を作成しました。
「1つのアニメーションステップ」を描くためにコードを変更することは、あまりにも多くの作業でした。
私はあなたのコードを使用して、すべてのフレームを事前に作成することを決めました(目的など)。
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

関連する問題