function explore3d(varargin)
%EXPLORE3D Explore your 3-D image interactively.
% EXPLORE3D(ax) activates the 3-D explorer for the axes specified
% by the handle "ax". Once activated you can use the keyboard to
% fly through your image in a manner similar to a flight simulator.
%
% Once activated, the arrow keys will allow you to look up, down,
% left, and right. In addition, the following keys produce the
% following actions:
%
% f - zoom forward
% b - zoom backward
% r - rotate right
% l - rotate left
% a - decrease your zooming step (for the "f" and "b" keys)
% s - increase your zooming step (for the "f" and "b" keys)
% z - decrease your angular step (for the arrow, "r", and "l" keys)
% x - increase your angular step (for the arrow, "r", and "l" keys)
% ESC - closes EXPLORE3D and restores original figure properties
%
% % EXAMPLE 1:
% surf(peaks)
% explore3d(gca)
% Now you can fly!
%
% % EXAMPLE 2:
% % Run this code and then try to find the sphere
% figure('color',[0 0 0])
% [x,y,z]=sphere;
% xspot=round(5*(rand-0.5));
% yspot=round(5*(rand-0.5));
% surf(x+xspot-0.5,y+yspot+0.5,z./3)
% hold on
% xwall=[-1 -1 1 1];
% ywall=[0 0 0 0];
% zwall=[-1 1 1 -1];
% patch([-10 -10 10 10],[-10 10 10 -10],[2 2 2 2]+eps,'b')
% patch([-10 -10 10 10],[-10 10 10 -10],[-2 -2 -2 -2]-eps,'r')
% for j=1:25,
% xspot=round(20*(rand-0.5));
% yspot=round(20*(rand-0.5));
% if round(rand),
% patch(xwall+xspot,ywall+yspot,zwall,rand(1,3))
% else
% patch(ywall+xspot,xwall+yspot,zwall,rand(1,3))
% end
% end
% view(3),axis([-15 15 -15 15 -5 5],'off')
% explore3d(gca)
% % Now see if you can find the sphere!
%
% By Mickey Stahl 2-26-02
% Engineering Development Group
% Aspiring Developer
if strcmp(class(varargin{1}),'double')
initialize(varargin{1})
else
feval(varargin{:})
end
function initialize(ax)
drawnow
handles.ax=ax;
handles.fig=get(ax,'parent');
handles.axesProperties=get(ax);
handles.figureProperties=get(handles.fig);
set(ax,...
'ALimMode','manual',...
'CameraTargetMode','manual',...
'camerapositionmode','manual',...
'CameraViewAngleMode','manual',...
'cameraupvectormode','manual',...
'projection','perspective')
handles.dist=sqrt(sum((ctarg(ax)-cpos(ax)).^2));
handles.step=80;
handles.radianTurn=80;
set(handles.fig,'doublebuffer','on',...
'keypressfcn','explore3d(''keypressfcn'',guidata(gcbo))')
path=ctarg(ax)-cpos(ax);
set(ax,'cameratarget',cpos(ax)+path./sqrt(sum(path.^2)));
guidata(handles.fig,handles)
function keypressfcn(handles)
ax=handles.ax;
c=abs(lower(get(handles.fig,'currentcharacter')));
persistent keydown;
if isempty(keydown)
keydown=1;
end
%try
if ~isempty(c) & keydown
keydown=0;
switch c
case 102
zoomcamera(handles,1)
case 98
zoomcamera(handles,-1)
case 30
movetarget(handles,1,1)
case 31
movetarget(handles,-1,1)
case 28
movetarget(handles,-1,0)
case 29
movetarget(handles,1,0)
case 115
if handles.step>1,
handles.step=handles.step-1;
end
case 97
handles.step=handles.step+1;
case 122
handles.radianTurn=handles.radianTurn+1;
case 120
if handles.radianTurn>1,
handles.radianTurn=handles.radianTurn-1;
end
case 114
rotatecamera(handles,1)
case 108
rotatecamera(handles,-1)
case 27
escape(handles)
end
if c==120 | c==122 | c==97 | c==115,
guidata(handles.fig,handles)
pause(0.05)
end
keydown=1;
end
%catch
% keydown=1;
%end
function rotatecamera(handles,right)
cp=cpos(handles.ax);
ct=ctarg(handles.ax)-cp;
cuv=cupvec(handles.ax);
right=right/handles.radianTurn;
rightline=cross(ct,cuv);
cuv=(cuv+right.*rightline);
cuv=cuv./sqrt(sum(cuv.^2));
set(handles.ax,...
'cameraupvector',cuv);
function movetarget(handles,direction,updown)
cp=cpos(handles.ax);
ct=ctarg(handles.ax)-cp;
cuv=cupvec(handles.ax);
direction=direction/handles.radianTurn;
if updown
cuv=cuv-direction.*ct;
ct=ct+direction.*cuv;
cuv=cuv./sqrt(sum(cuv.^2));
ct=ct./sqrt(sum(ct.^2));
else
rightline=cross(ct,cuv);
ct=(ct+direction.*rightline);
ct=ct./sqrt(sum(ct.^2));
end
set(handles.ax,...
'cameratarget',cp+ct,...
'cameraupvector',cuv);
function zoomcamera(handles,in)
ax=handles.ax;
path=ctarg(ax)-cpos(ax);
path=in*handles.dist.*path./(sqrt(sum(path.^2))*handles.step);
newcp = cpos(ax) + path;
newtarg=ctarg(ax)+ path;
set(ax,'cameraposition',newcp,...
'cameratarget',newtarg)
function out = cpos(ax)
out = get(ax,'CameraPosition');
function out = ctarg(ax)
out = get(ax,'CameraTarget');
function out = cupvec(ax)
out = get(ax,'CameraUpVector');
function escape(handles)
h=[handles.fig handles.ax];
props(1).struct=handles.figureProperties;
props(2).struct=handles.axesProperties;
for j=1:2,
names=fieldnames(props(j).struct);
for k=1:length(names)
try
set(h(j),names{k},getfield(props(j).struct,names{k}))
catch
end
end
end