Search All of the Math Forum:

Views expressed in these public forums are not endorsed by NCTM or The Math Forum.

Notice: We are no longer accepting new posts, but the forums will continue to be readable.

Topic: Rotating 3D plots with the mouse
Replies: 1   Last Post: Aug 8, 1996 2:58 PM

 Messages: [ Previous | Next ]
 Andrew Fitzgibbon Posts: 6 Registered: 12/7/04
Rotating 3D plots with the mouse
Posted: Aug 6, 1996 11:41 AM

Just hacked this, others may be interested. It allows you to use the mouse
to rotate a 3D plot (just points at the moment, but the rest is an exercise

Having copied the files x3d.m and exp2mat.m somewhere, try.

[x,y,z]=sphere(20);
p = [x(:) y(:) z(:)];
x3d(p * diag([1 .2 .3]))

Button 1 rotates, 2 translates, 3 scales.

**** FILE exp2mat.m
function M = exp2mat(r)
% EXP2MAT Convert from exponential to matrix rotation parameterization.

% Andrew Fitzgibbon <awf@robots.ox.ac.uk>

angle = norm(r);

if (angle < eps)
M=eye(3,3);
else
ef = sin(angle)/angle;
gee = (1.0 - cos(angle))/ (angle*angle);
H = [0, -r(3), r(2); r(3), 0, -r(1); -r(2), r(1), 0];
M = (H*H)*gee + H*ef + eye(3,3);
end

**** FILE x3d.m
function x3d(arg, arg2, arg3)
% X3D 3D Viewer

% Andrew Fitzgibbon <awf@robots.ox.ac.uk>

global point_handles
global line_handles
global P
global x3d_viewmatrix
global x3d_mag
global x3d_camdist
global down_pt
global down_matrix
global down_mag

if ~isstr(arg)
R = eye(3);
if nargin > 1
if isstr(arg2)
if strcmp(arg2, 'init')
x3d_viewmatrix = [];
end
end
end
if isempty(x3d_viewmatrix)
x3d_viewmatrix = [R zeros(3,1)];
x3d_camdist = 20;
x3d_mag = 1000 * x3d_camdist / trace(cov(P));
end

P = [arg'; ones(1, length(arg))];

p2 = x3d_viewmatrix * P;
s = x3d_mag./(x3d_camdist + p2(3,:));
x = p2(1,:).*s;
y = p2(2,:).*s;
point_handles = plot(x, y, 'wo');
set(point_handles, 'markersize', 2);
axis equal
hold on
title('View3d')
axis([-1 1 -1 1])

set(gcf, 'WindowButtonMotionFcn', '');
set(gca, 'ButtonDown', 'x3d(''down'')');
set(gcf, 'WindowButtonDownFcn', 'x3d(''down'')');
set(gcf, 'WindowButtonUp', 'x3d(''up'')');
set(gca, 'position', [0 0 1 1])
axis off
hold off
elseif strcmp(arg, 'down')

% Install motion fun
set(gcf, 'WindowButtonMotionFcn', 'x3d(''motion'')');
down_pt = get(gca,'currentpoint');
down_matrix = x3d_viewmatrix;
down_mag = x3d_mag;
xormode(point_handles);

elseif strcmp(arg, 'up')

%% Clear motion function
set(gcf, 'WindowButtonMotionFcn', '');
set(point_handles, 'erasemode', 'normal');
else

%% We're on
pt=get(gca,'currentpoint');
x0=pt(1,1);
y0=pt(1,2);
d = pt - down_pt;
dx = d(1,1);
dy = d(1,2);

R = down_matrix(1:3,1:3);
t = down_matrix(1:3,4);

button = get(gcf, 'selectiontype');
if button(1) == 'n'
% Button 1 -- rotate
Ry = exp2mat(dx * pi/2 * [0 1 0]);
Rx = exp2mat(dy * pi/2 * [1 0 0]);
R = Rx * Ry * R;
elseif button(1) == 'e'
% Button 2 -- translate
t = t + [dx dy 0]' * x3d_mag;
elseif button(1) == 'a'
% Button 3
x3d_mag = down_mag * (1 + dy);
elseif button(1) == 'o'
% Doubleclick
end

x3d_viewmatrix = [R t];

p2 = x3d_viewmatrix * P;
s = x3d_mag./(x3d_camdist + p2(3,:));
x = p2(1,:).*s;
y = p2(2,:).*s;

set(point_handles,'xdata', x, 'ydata', y);
drawnow
end
--
Andrew Fitzgibbon, awf@robots.ox.ac.uk
Oxford Robotics Research Group +44 01865 273127