How to make a smooth rotation of a 3D plot in MATLAB? -
if try rotate camera around current figure plot3 using
while true; camorbit(0.9,-0.1); drawnow; end then rotation periodically hangs while (example) on 8-core macpro.
can make smooth?
edit1:
while there no solution original question yet, i've managed make better movie getframe function. doesn't allow recording free-hand rotation, though, , quite buggy in matlab2010b mac.
%# fix wrong figure position in matlab2010b mac - depends on 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); i=1:fps*sec camorbit(0.9,-0.1); writevideo(vidobj,getframe(gcf, correctedposition)); end close(vidobj); edit2:
i created similar thread @ matlab central.
edit3:
you can try downloading 1 of figures.
i it's large number of points drawing that's causing slowdown. 1 option downsample.. use lower-level functions draw (check this related post comparison of plot3/scatter3/line performance).
consider animation below optimized speed:
[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 aspect ratio override stretch-to-fill behaviour axis vis3d %# fix axes limits manually %#set(gca, 'xlim',[-1 1], 'ylim',[-1 1], 'zlim',[-1 1]) axis manual %# maybe remove tick labels %set(gca, 'xticklabel',[], 'yticklabel',[], 'zticklabel',[]) %# animate (until figure closed) while ishandle(hfig); camorbit(0.9,-0.1); drawnow; end 
note how using z-buffer renderer, , turned off backingstore property.
edit:
if understood correctly, trying record screencast (using 3rd-party app), while manually rotate figure, in case these manual rotations "jumpy". on other animating figure camorbit/view in while-loop running smooth...
i propose alternative solution: start rotating figure using mouse , write these view configurations @ each step (azimuth,elevation). can replay them using view function while recording video, like:
v = [...]; %# matrix each row specify az/el of view i=1:size(v,1) view( v(i,:) ) drawnow end the downside have press/rotate/release using mouse in small steps (the rotate3d object not expose mouse-motion event)
i wrote simple function in process. loads saved figure, enable 3d-rotation, , keeps track of intermediate position @ each step. once finished, press "done" button return list of views...
function v = rotationdemo(figfilename) views = []; %# list of views (az,el) hfig = hgload(figfilename); %# load saved figure views(1,:) = get(gca,'view'); %# store initial view %# add button, used terminate process hbutton = uicontrol('style','pushbutton', 'position',[400 1 80 20], ... 'string','done?', 'callback',@buttoncallback); set(hfig, 'toolbar','figure') %# restore toolbar %# start 3d rotation, , handle post-callback record intermediate views h = rotate3d(hfig); %# rotation object set(h, 'actionpostcallback',@rotatecallback) set(h, 'enable','on') %# enable rotation msgbox('rotate view step-by-step', 'rotate3d', 'warn', 'modal') uiwait(hfig) %# wait user click button delete(hbutton) %# delete button on finish set(h, 'enable','off') %# disable rotation v = round(views); %# return list of views %# callback functions function rotatecallback(o,e) views(end+1,:) = get(e.axes,'view'); %# add current view list end function buttoncallback(o,e) uiresume(gcbf) %# uiresume(hfig) end end 
you can call above function, replay animation:
v = rotationdemo('smooth_rotation.fig'); i=1:size(v,1) view(v(i,:)) drawnow end we can smooth transitions simple interpolation:
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)] ); i=1:size(vv,1) view(vv(i,:)) drawnow %# or pause(..) slow down end as side note, should mention rotate3d , camorbit have different effects. rotate3d changes view property of current axis, while camorbit controls camera properties cameratarget/cameraposition/cameraupvector of current axis.
Comments
Post a Comment