classdef spin3dplot
%SPIN3DPLOT Why so stiff? Take a spin!
% This class allows you to spin your 3D plots.
% At this time, only mesh and surf are supported.
% Your SURFACEPLOT object will have a black background by default.
% This results in your plot automagically turn awesome.
% If you're boring and stiff, you may disable the black in the
% constructor method. But you wouldn't do that, would you?
%
% Side Note: The function is currently effective only on mesh and surf
% plots. Maybe I'll add in more as time comes. Maybe I'll get distracted
% whenever I set out on this task. Maybe...
% Copyright 2013 TAN YU ANG tan.ya@techsource.com.my
% $Revision: 0.1 $ $Date: 2013/02/28 20:20:20 $
% Customised function.
properties
xdata
ydata
zdata
maxidx
hax
htimer
end
methods
function o = spin3dplot(h,varargin)
%SPIN3DPLOTX Construct a spin object.
%
% S = SPIN3DPLOT(h) adds a spin to a Surfaceplot graphics
% object. It also sprinkles a little bit of awesomeness on you.
%
% Note that this function only works with the mesh and surf
% plots. By default, black mode is set. This means that face
% color and background will all be black, making a cool looking
% plot.
%
% I would make the whole window black, but I'm betting on an
% awesome UI from Mathworks in the 2013b release. It might
% happen. It might not.
%
% Example:
% % To construct a spin object feed in a handle to a surf and
% mesh plot:
% h = surf(magic(50));
% s = spin3dplot(h);
% % To begin the fun:
% s.start;
% % To pause the spin:
% s.pause;
% % To resume:
% s.start;
% % To close the graph and remove the timer:
% s.stop;
%
% Create timer object
o.htimer = timer('ExecutionMode', 'fixedRate', ...
'Period', .1, ...
'UserData', 1);
% Attach plot to object
o = o.attach(h);
end
function o = attach(o,h,varargin)
%ATTACH Attaches SURFACEPLOT object handle.
%
% ATTACH(handle) attaches the SURFACEPLOT object handle to
% SPIN3DPLOT object. This is pre-requisite work for all the
% impending awesomeness.
%
%
o.hax = get(h,'Parent');
% 'Transparent' /Black background
black = true;
if (black)
black = [0 0 0];
set(h,'FaceColor', black);
set(h,'EdgeColor', 'interp');
set(get(get(h,'Parent'),'Parent'),'Color', black)
set(o.hax,'Color',black);
else
set(o.hax,'Color',[0.800000011920929 0.800000011920929 0.800000011920929]);
end
% Specify camera distance from target to maximum of x and y
camdist = (abs(get(o.hax,'CameraPosition')));
dist = max(camdist(1:2));
% Specify point of focus
center = get(gca,'CameraTarget');
% Define camera trail
theta = 0:.05:2*pi;
o.maxidx = length(theta); % trail indexing
o.xdata = center(1)-dist*sin(theta);
o.ydata = center(2)- dist*cos(theta);
o.zdata = camdist(3);
% Tighten the axes
dx= reshape(get(get(o.hax,'Children'),'XData'),[],1);
dy= reshape(get(get(o.hax,'Children'),'YData'),[],1);
temp = axis;
axis([min(dx) max(dx) min(dy) max(dy) temp(5) temp(6)]);
set(o.htimer,'TimerFcn', @(v1,v2)(o.step));
% Fix Camera View Angle
CameraViewAngle = get(o.hax,'CameraViewAngle');
set(o.hax,'CameraViewAngle',CameraViewAngle)
end
function start(o)
%START Starts spinning
%
% START(o) starts spinning.
%
%
axes(o.hax)
try
start(o.htimer)
end
end
function o = step(o)
%STEP Callback function
%
% STEP(o) is called by the timer object periodically,
% incrementing the idx variable. This variable serves as the
% index to the position of the viewing camera, and then promptly
% refreshes its position.
%
%
% Increment and update index value
idx = get(o.htimer,'UserData');
if idx<o.maxidx
idx = idx + 1;
else
idx = 1;
end
set(o.htimer,'UserData',idx);
% Set camera position
set(o.hax,'CameraPosition',[o.xdata(idx) o.ydata(idx) o.zdata]);
end
function pause(o)
%PAUSE Pauses the spinning
%
% PAUSE(o) pauses the spinning.
%
%
stop(o.htimer)
end
function stop(o)
%STOP Stops the silliness
%
% STOP(o) stops the spinning. Worst of all, it closes the
% surface plot, erasing all the trace of awesomeness that took
% place just not too long ago.
%
% Sigh, oh well. Let's just get back to work.
%
%
stop(o.htimer)
delete(o.htimer)
close(get(o.hax,'Parent'))
end
end
end