|
|
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 for the reader :-)
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 Home Page "Never say there is no way"
|
|