viewmtx example

Explore code from

viewmtx.m

Define vector that draws a cube

close all
clear
%          1      2      3      4      5      6      7      8
vcube = [ 0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1]';
idx = [1 2 3 4 1 5 6 7 8 5 6 2 3 7 8 4];
vert(1,:) = vcube(1,:);
vert(2,:) = vcube(2,:);
vert(3,:) = vcube(3,:);

% These vectors trace the edges of a unit cube:
x = vert(1,idx);
y = vert(2,idx);
z = vert(3,idx);

Transform the cube vectors to the screen and plot the object:

A = viewmtx(-37.5,30,25);
[m,n] = size(x);
x4d = [x(:),y(:),z(:),ones(m*n,1)]';
x2d = A*x4d;
x2 = zeros(m,n); y2 = zeros(m,n);
x2(:) = x2d(1,:)./x2d(4,:);
y2(:) = x2d(2,:)./x2d(4,:);
plot(x2,y2)

Use plot3 to display cube (same nominal parameters as above) save the plot as cube.eps

plot3(x,y,z);
view(-37.5,30);
camproj('perspective');
camva(25);
set(gcf,'Position',[300 200 800 600]);
set(gca,'Position',[0 0 1 1]);
v1 = get(gca,'CameraPosition');
fprintf('camera position: %g %g %g\n',v1);
v2 = get(gca,'CameraTarget');
fprintf('camera target: %g %g %g\n',v2);
camera position: -4.06571 -5.45015 4.83013
camera target: 0.5 0.5 0.5

view vs. viewmtx

T = viewmtx(-37.5,30)
view(-37.5,30);
M = view

% look at rotation matrices

R1 = T(1:3,1:3)
R2 = M(1:3,1:3)

fprintf('det(R1) %g det(R2) %g\n',det(R1),det(R2));

t1 = R1'*T(1:3,4)
t2 = R2'*M(1:3,4)

fprintf('camera position: %g %g %g\n',v1);
T =

    0.7934   -0.6088         0         0
    0.3044    0.3967    0.8660         0
   -0.5272   -0.6871    0.5000         0
         0         0         0    1.0000


M =

    0.7934   -0.6088         0   -0.0923
    0.3044    0.3967    0.8660   -0.7835
    0.5272    0.6871   -0.5000    8.3031
         0         0         0    1.0000


R1 =

    0.7934   -0.6088         0
    0.3044    0.3967    0.8660
   -0.5272   -0.6871    0.5000


R2 =

    0.7934   -0.6088         0
    0.3044    0.3967    0.8660
    0.5272    0.6871   -0.5000

det(R1) 1 det(R2) -1

t1 =

     0
     0
     0


t2 =

    4.0657
    5.4502
   -4.8301

camera position: -4.06571 -5.45015 4.83013

now perspective

az = -37.5;
el = 30;
phi = 25;
T = viewmtx(-37.5,30,25)
f = sqrt(2)/2/+tan(phi*pi/360);
P = [ 1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 -1/f 1];
test = inv(P)*T
T =

    0.7934   -0.6088         0   -0.0923
    0.3044    0.3967    0.8660   -0.7835
   -0.5272   -0.6871    0.5000   -0.5089
    0.1653    0.2154   -0.1568    1.1595


test =

    0.7934   -0.6088         0   -0.0923
    0.3044    0.3967    0.8660   -0.7835
   -0.5272   -0.6871    0.5000   -0.5089
         0         0         0    1.0000

work through matrix

R = T(1:3,1:3);
% Transformation to move origin of object coordinate system to TARGET
pos = campos
O1 = [eye(4,3),[-pos';1]];

R = [R [0 0 0]'; [0 0 0 1]]
T = P*R*O1

el = el*pi/180;
az = az*pi/180;
% default target calculation (in viewmtx)
default_target = 0.5 + sqrt(3)/2*[cos(el)*sin(az);-cos(el)*cos(az);sin(el)]
pos =

   -4.0657   -5.4502    4.8301


R =

    0.7934   -0.6088         0         0
    0.3044    0.3967    0.8660         0
   -0.5272   -0.6871    0.5000         0
         0         0         0    1.0000


T =

    0.7934   -0.6088         0   -0.0923
    0.3044    0.3967    0.8660   -0.7835
   -0.5272   -0.6871    0.5000   -8.3031
    0.1653    0.2154   -0.1568    3.6032


default_target =

    0.0434
   -0.0950
    0.9330

pts = [v2 1];
pt = T*pts'
x0 = pt(1)/pt(4);
y0 = pt(2)/pt(4);
z0 = pt(3)/pt(4);
fprintf('transformed target %f %f %f\n',x0,y0,z0);
fprintf('focal length %g\n',f);
pt =

   -0.0000
    0.0000
   -8.6603
    3.7152

transformed target -0.000000 0.000000 -2.331037
focal length 3.18955
A = [x' y' z' ones(length(x),1)];
htpts = T*A';
x3 = htpts(1,:)./htpts(4,:);
y3 = htpts(2,:)./htpts(4,:);
z3 = htpts(3,:)./htpts(4,:);
close all
plot(x3,y3,'k');
axis equal

% get points on edge of cube
verts = unique(A,'rows');
%verts = [verts ones(length(verts),1)];
[B ix] = sort(verts(:,3));
B = verts(ix,:);

htpts = T*B';
xpts = htpts(1,:)./htpts(4,:);
ypts = htpts(2,:)./htpts(4,:);
zpts = htpts(3,:)./htpts(4,:);

disp([xpts' ypts' zpts'])

hold on
plot(xpts,ypts,'ko');
axis equal

xo = 0.005;
yo = 0.005;
for n=1:8
    str = sprintf('%d',n);
    text(xpts(n)+xo,ypts(n)+yo,str);
end
hold off
   -0.0256   -0.2175   -2.3044
   -0.1836   -0.1013   -2.3543
    0.1860   -0.1271   -2.3432
    0.0232   -0.0207   -2.3889
   -0.0268    0.0239   -2.2641
   -0.1914    0.1309   -2.3185
    0.1941    0.1071   -2.3064
    0.0241    0.2047   -2.3562

rgb = imread('cube.jpg');
[ny nx nz] = size(rgb);
fprintf('image size %g %g\n',nx,ny);
imshow(rgb)
image size 800 600

cube data obtained from *.eps file

% there are only 12 unique rows
load cube
plot([data(1,1) data(1,3)],[data(1,2) data(1,4)],'r')
hold on
for n=2:15
plot([data(n,1) data(n,3)],[data(n,2) data(n,4)])
end
hold off
axis ij

% get unique points of cube
pt = [data(:,1) data(:,2)];
pts = flipud(unique(pt,'rows'));
% arrange in same order as starting points (xpts, ypts)
ix = [5 7 2 4 6 8 1 3];
spts = pts(ix,:)

for n=1:length(spts)
    str = sprintf('%d',n);
    text(spts(n,1),spts(n,2),str);
end
spts =

        3464        3849
        2649        3224
        4566        3360
        3717        2805
        3455        2571
        2593        2012
        4624        2134
        3724        1641

look at pixel scale between plot3 pixel values and our calculated values

scl = 1000;
cx = polyfit(xpts',spts(:,1)/scl,1)
cy = polyfit(ypts',spts(:,2)/scl,1)

close all
xr = [-0.2 0.2];
plot(xpts,spts(:,1)/1000,'ko',xr,polyval(cx,xr));
grid
xlabel('calculated x-values');
ylabel('x-values from cube.eps file');
figure
xr = [-0.25 0.25];
plot(ypts,spts(:,2)/1000,'ko',xr,polyval(cy,xr));
grid
xlabel('calculated y-values');
ylabel('y-values from cube.eps file');
cx =

    5.2291    3.5990


cy =

   -5.2303    2.6995

xfit = polyval(cx,xpts');
yfit = polyval(cy,ypts');
xd = spts(:,1)-xfit*scl;
yd = spts(:,2)-yfit*scl;
plot(xd,yd,'ko')
grid;
axis equal
xlabel('x error (pixels)');
ylabel('y error (pixels)');
dm = 0.2;
for n=1:8
    str = sprintf('%d',n);
    text(xd(n)+dm*rand,yd(n)+dm*rand,str);
end
maxerr = squeeze(max([xd; yd]));
fprintf('maxerror %e\n',maxerr);
maxerror 1.229105e+01