8

plot3を使用して現在の図の周りにカメラを回転させようとすると

while true; camorbit(0.9,-0.1); drawnow; end

その後、 8 コアの MacPro でも定期的にローテーションがしばらくハングします (例)。

スムーズにできますか?

EDIT1:

元の質問に対する解決策はまだありませんが、getframe機能を備えたより良いムービーを作成することができました。ただし、フリーハンドの回転を記録することはできず、Mac 用の MATLAB2010b ではかなりバグがあります。

%# fix wrong figure position in MATLAB2010b for Mac - depends on your layout
correctedPosition = get(gcf,'Position') + [21 -125 0 0];

fps = 60; sec = 10;

vidObj = VideoWriter('newfile.avi');
vidObj.Quality = 100;
vidObj.FrameRate = fps;

open(vidObj);
for i=1:fps*sec
  camorbit(0.9,-0.1);
  writeVideo(vidObj,getframe(gcf, correctedPosition));
end
close(vidObj);

EDIT2:

MATLAB Centralで同様のスレッドを作成しました。

EDIT3:

私の図の 1 つをダウンロードして、自分で試すことができます。

4

3 に答える 3

4

減速の原因となっているのは、描画しているポイントの数が多いことだと思います。1 つのオプションはダウンサンプリングです。また、下位レベルの関数を使用して描画することもできます ( plot3/scatter3/line のパフォーマンスの比較については、この関連記事を確認してください)。

速度のために最適化された以下のアニメーションを検討してください。

[X Y Z] = sphere(64);
X = X(:); Y = Y(:); Z = Z(:);

%# set-up figure
hFig = figure('Backingstore','off', 'renderer','zbuffer');

%# use lower-level function LINE
line(0.50*[X,X], 0.50*[Y,Y], 0.50*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','r')
line(0.75*[X,X], 0.75*[Y,Y], 0.75*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','g')
line(1.00*[X,X], 1.00*[Y,Y], 1.00*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','b')
view(3)

%# freeze the aspect ratio to override stretch-to-fill behaviour
axis vis3d

%# fix the axes limits manually
%#set(gca, 'xlim',[-1 1], 'ylim',[-1 1], 'zlim',[-1 1])
axis manual

%# maybe even remove the tick labels
%set(gca, 'xticklabel',[], 'yticklabel',[], 'zticklabel',[])

%# animate (until figure is closed)
while ishandle(hFig); camorbit(0.9,-0.1); drawnow; end

代替テキスト

Z-buffer rendererをどのように使用し、 Backingstoreプロパティをオフにしているかに注意してください。


編集:

私が正しく理解している場合、あなたがやろうとしているのは、フィギュアを手動で回転させながら(サードパーティのアプリを使用して)スクリーンキャストを記録することですが、あなたの場合、これらの手動回転は「ぎくしゃく」しています。一方、whileループでCAMORBIT / VIEWを使用してフィギュアをアニメーション化すると、スムーズに実行されます...

別の解決策を提案します。マウスを使用して図を回転させることから始め、各ステップ (方位角、仰角) でこれらのビュー構成を記述します。次に、ビデオの録画中に VIEW 関数を使用して、次のように再生できます。

v = [...];   %# matrix where each row specify Az/El of view
for i=1:size(v,1)
    view( v(i,:) )
    drawnow
end

欠点は、マウスを使用して小さなステップで押す/回転する/離す必要があることです (ROTATE3D オブジェクトはマウスモーション イベントを公開しません)。

このプロセスで役立つ簡単な関数を作成しました。保存された図を読み込み、3D 回転を有効にし、各ステップで中間位置を追跡します。終了したら、[完了] ボタンを押してビューのリストを返します...

function v = rotationDemo(figFileName)
    views = [];                     %# list of views (Az,El)

    hFig = hgload(figFileName);     %# load the saved figure

    views(1,:) = get(gca,'View');   %# store initial view

    %# add a button, used to terminate the process
    hButton = uicontrol('Style','pushbutton', 'Position',[400 1 80 20], ...
                        'String','Done?', 'Callback',@buttonCallback);
    set(hFig, 'Toolbar','figure')   %# restore toolbar

    %# start 3d rotation, and handle post-callback to record intermediate views
    h = rotate3d(hFig);             %# get rotation object
    set(h, 'ActionPostCallback',@rotateCallback)
    set(h, 'Enable','on')           %# enable rotation

    msgbox('Rotate the view step-by-step', 'rotate3d', 'warn', 'modal')

    uiwait(hFig)                    %# wait for user to click button
    delete(hButton)                 %# delete button on finish
    set(h, 'Enable','off')          %# disable rotation
    v = round(views);               %# return the list of views

    %# callback functions
    function rotateCallback(o,e)
        views(end+1,:) = get(e.Axes,'View');  %# add current view to list
    end
    function buttonCallback(o,e)
        uiresume(gcbf)                        %# uiresume(hFig)
    end
end

代替テキスト

上記の関数を呼び出して、アニメーションを再生できます。

v = rotationDemo('smooth_rotation.fig');
for i=1:size(v,1)
    view(v(i,:))
    drawnow
end

単純な補間によって遷移を滑らかにすることができます。

v = rotationDemo('smooth_rotation.fig');
n = size(v,1);
nn = linspace(1,n,100)';     %'# use 100 steps
vv = round( [interp1(v(:,1),nn) interp1(v(:,2),nn)] );
for i=1:size(vv,1)
    view(vv(i,:))
    DRAWNOW                  %# or PAUSE(..) to slow it down
end

余談ですが、ROTATE3D と CAMORBIT の効果は異なります。ROTATE3D は現在の軸のプロパティを変更し、 CAMORBIT は/ /現在の軸Viewのカメラ プロパティを制御します。CameraTargetCameraPositionCameraUpVector

于 2010-12-02T20:26:41.710 に答える
2

通常のMATLABフィギュアで話しているのと同じけいれん的な動きを認識しています。しかし、Amroのコードを実行して、ムービー(* .AVI)を作成しようとすると、Macノートブックでもスムーズに見えます。

私が使用した映画製作コードは次のとおりです。

%次のように、映画の作成中にフィギュア「オフ」の「表示」プロパティを追加しました(ただし、これによって状況が改善されるかどうかは正確にはわかりません)。

hFig = figure('Backingstore'、'off'、'visible'、'off'、'renderer'、'zbuffer');

%次に、次のように、Amroのwhileループを単純なAVI生成ループに置き換えました。

aviobj = avifile('test.avi'); %はAVIファイルを作成します

I = 1:360の場合

camorbit(0.9、-0.1); drawow;

aviobj = addframe(aviobj、hFig); %AVIファイルにフレームを追加します

終わり

aviobj = close(aviobj); %はAVIファイルを閉じます

close(hFig); %close hFig

質問:図をレンダリングする前に、いくつかのポイントを間引くか、密度マップを作成するのに役立ちますか?

[参照。さまざまなレンダリングオプションについて:http://www.mathworks.com/support/tech-notes/1200/1201.html ]

上記のコメントがお役に立てば幸いです。

于 2010-12-03T00:47:55.427 に答える
1

これがあなたの問題に役立つかどうかはわかりませんが、何らかの理由で、グラフィックウィンドウの更新を強制するpause(0.001)よりもうまくいきましたdrawnow

また、rotate3d の方が速いかどうかも確認できます。

matlab の多くの関数はマルチスレッドをサポートしていないため、コアの数はそれほど重要ではありません。


回避策は、そのまま続行することですが、Figure ウィンドウをムービー ファイルに書き込みます。その後、ムービーを再生できます。

于 2010-12-02T20:18:27.457 に答える