In Matlab you can specify the viewpoint of a 3D object with the view function. Combining a few selected view angles with an interpolant allows you to smoothly pan over an object. The code below explains how to do this and then how to make a gif out of the result.

The code below is useful for panning between several specified view angles. You could replace the interpolant lines with function calls. For example, try v1 = 30 + 10*cos(2*pi*fineOrdinate(i)); v2 = 30 + 10*sin(2*pi*fineOrdinate(i));.

clc; clear all;

% Table of Contents
% 1) make data, pan over a 3D figure
% 2) show interpolation results to explain spline problems
% 3) make a gif!

%% example data
nx = 100;
ny = 100;
[xg,yg] = meshgrid(linspace(-1,1,nx).',linspace(-1,1,ny).');
x = reshape(xg,nx*ny,1);
y = reshape(yg,nx*ny,1);

z = cos(pi*x).*sin(pi*y).*exp(-1*(x.^2+y.^2));

%% make a scatter3 plot to visualize in 3D
% color by the z value
figure(1); clf;
scatter3(x,y,z,200,z,'filled');
xlabel('x'); ylabel('y'); zlabel('z');
colormap jet;

%% panning over the 3D visualization
% matlab sets the view angle with: view(v1,v2), where v1 and v2 determine
% orientation of the 3D viewer
%
% for instance, view(0,90) gives a top-down look at the x-y plane
%
%
% To pan, first provide a set of view angles and an ordinate that will
% determine how quickly you want to pan from one view to the next.
%
% The closer the ordinate values, the faster that transition will occur.
%
% V = [ o1 v11 v12;
% o2 v21 v22;
% o3 v31 v32;
% o4 v41 v42];
%
% Finding these angles takes experiment.

V = [1 0 90;
2 5 86;
3 45 38;
4 70 22;
5 95 30;
8 157 44]; % this ordinate is further because the view angles change a lot

% Next specify a desired number of frames
nFrames = 60;
fineOrdinate = linspace(min(V(:,1)),max(V(:,1)),nFrames).';

% Now simply iterate through the 'fineOrdinate' vector, doing interpolation
% between the view angles to pan.

method = 'pchip'; % 'pchip' preserves shape (no wiggles) and is probably a good choice here
figure(1); % get back to the figure
for i = 1:nFrames
v1 = interp1(V(:,1),V(:,2),fineOrdinate(i),method);
v2 = interp1(V(:,1),V(:,3),fineOrdinate(i),method);
view(v1,v2);
getframe;
end

%% sometimes spline interpolation will mess with things due to wiggles
% the code below will plot the interpolated view angles
%
% The data below (in blog post) will show a notable wiggle early in the
% movie if spline interpolation is used instead of linear.
%
% The
%
% V = [1 0 90;
% 2 5 86;
% 3 45 38;
% 4 70 22;
% 5 95 30;
% 8 157 44];
%
v1All = interp1(V(:,1),V(:,2),fineOrdinate,method);
v2All = interp1(V(:,1),V(:,3),fineOrdinate,method);
figure(2);
plot(V(:,1),V(:,2),'bo',V(:,1),V(:,3),'rs',fineOrdinate,v1All,'b-',fineOrdinate,v2All,'r--');
legend('v1','v2','v1 pan','v2 pan','Location','Best');

%% make a gif!
filename = 'panning-test.gif';

figure(1); % get back to the figure
for i = 1:nFrames
v1 = interp1(V(:,1),V(:,2),fineOrdinate(i),method);
v2 = interp1(V(:,1),V(:,3),fineOrdinate(i),method);
view(v1,v2);
drawnow;
frame = getframe;
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if i == 1;
imwrite(imind,cm,filename,'gif','Loopcount',Inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
end
disp('- Done making gif');

Categories: Uncategorized

1 Comment

Mike Hansen · March 2, 2016 at 10:48 PM

If you want to actually see the axis labels in the gif, you have to use getframe(gcf) instead of just getframe. I don’t know why this comment shows up in all caps. I am not trying to yell!

Leave a Reply