8

如果我尝试plot3使用以下方式围绕我当前的人物旋转相机

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

然后即使在 8 核 MacPro 上,旋转也会定期挂起一段时间(例如)。

我可以让它顺利吗?

编辑1:

虽然我最初的问题还没有解决方案,但我已经设法制作了一部具有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);

编辑2:

我在MATLAB Central创建了一个类似的线程。

编辑3:

你可以自己下载我的一个图试试。

4

3 回答 3

4

我会说这是您绘制的大量点导致减速。一种选择是下采样。您也可以使用较低级别的函数进行绘制(查看此相关帖子以比较 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渲染器,并关闭Backingstore属性。


编辑:

如果我理解正确,您要做的是录制截屏视频(使用第 3 方应用程序),同时手动旋转图形,但在您的情况下,这些手动旋转是“跳跃的”。另一方面,在 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改变View当前轴的属性,而CAMORBIT控制当前轴的相机属性CameraTarget// 。CameraPositionCameraUpVector

于 2010-12-02T20:26:41.710 回答
2

我认识到您在常规 MATLAB 图上所说的相同的抽搐动作。但是当我尝试运行 Amro 的代码、创建电影 (*.AVI) 时,它在我的 Mac 笔记本上看起来也很流畅。

我使用的电影制作代码如下:

%在制作电影时添加了图形“关闭”的“可见”属性(尽管我不确定这是否会使情况变得更好),如下所示:

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

% 然后,我用一个简单的 AVI 制作循环替换了 Amro 的 while-loop,如下:

aviobj=avifile('test.avi'); % 创建 AVI 文件

对于 I=1:360

凸轮(0.9,-0.1);拉丝;

aviobj=addframe(aviobj,hFig); % 将帧添加到 AVI 文件

结尾

aviobj=关闭(aviobj);%关闭​​ AVI 文件

关闭(hFig);%关闭​​ hFig

问题:在渲染图形之前抽取一些点或创建密度图会有所帮助吗?

[参考。关于各种渲染选项: http: //www.mathworks.com/support/tech-notes/1200/1201.html ]

我希望上面的评论会有所帮助。

于 2010-12-03T00:47:55.427 回答
1

我不知道这是否对您的问题有帮助,但由于某种原因,我pause(0.001)drawnow强制更新图形窗口更成功

您可能还会看到 rotate3d 是否更快。

内核的数量并不像你想象的那么重要,因为 matlab 中的许多函数不支持多线程。


一种解决方法是像现在一样继续,但将图形窗口写入电影文件。然后您可以播放电影。

于 2010-12-02T20:18:27.457 回答