- /
-
Quaternion demo
on 11 Oct 2024
- 18
- 320
- 0
- 5
- 1939
Cite your audio source here (if applicable):
drawframe(1);
Write your drawframe function below
function drawframe(f)
% This is mostly meant to serve as a guideline for how to use matlab camera
% settings with the aid of quaternions. Quaternions are a convenient way
% for representating rotations. Quaternions are vectors of 4 values, in the
% present case 3 of them representing an orientation vector, and the fourth
% a rotation value. They make it easy to define an arbitrary rotation without
% running into the gimble-lock issues of Euler angles, and it makes
% rolling the camera around a trajectory a piece of cake.
%
% No sound, sorry.
persistent crts rts cps p clk
o=@ones;
l=@linspace;
c=@cumsum;
s=@surf;
if f==1
% 1) Define the camera path. Make it tilt up then down, as if
% flying through some obstacles. To do this a set of pitch angles will be
% defined, which will be integrated and smoothed to get vector pitch
% in the z-dimension.
pch=[zeros(1,8),o(1,8)/8*30,o(1,8)/8*-30,o(1,8)/8*-90,zeros(1,32),o(1,8)/8*-30,o(1,8)/8*30,o(1,8)/8*90,zeros(1,8)];
pch=conv(pch,hann(9)'/sum(hann(9)),'same'); % For smooth transitions...
% Total pitch of direction vector
cpch=c(pch)/180*pi;
% direction vector
rt=@(x)[cos(x),-sin(x);sin(x),cos(x)]*[1;0];
for n=1:length(pch)
rts(:,n)=rt(cpch(n));
end
% Integrate direction vector to get position...
crts=c(rts')';
% 2) Now we have the camera / flight path, let's define our roll angle. I'm
% defining this piecewise, and it will be absolute roll angle around the
% path of motion.
ags=[l(0,1,30).^2*pi,zeros(1,26)+pi, l(0,1,30).^2*pi+pi, zeros(1,10)+2*pi];
agf=conv([ags, ags+2*pi,ags+4*pi],hann(21)'/sum(hann(21)),'same'); % Smooth
ags=agf(97:192)-2*pi;
% Now create camera up angle using the quaternion rotation
rt3 = [rts(1,:);0*rts(1,:);rts(2,:)];
cup = [-rt3(3,:);0*rt3(2,:);rt3(1,:)];
for n = 1:size(rts, 2)
MT = Q2M(rt3(:,n),ags(n)); % Quaternion to rotation matrix function
clk(:,n)=MT*cup(:,n);
end
% Now create our scene. This will be made of a couple textured boxes.
[cx,cy,cz]=cylinder(o(2,1),4);
cx2=(cx-cy)/2;
cy2=(cx+cy)/2;
ccx=cz-.5;
ccy=cy2+.5;
ccz=cx2-.5;
scl=200;
tx=rand(250*6,1000*6);
tx(:,size(tx,2)/2:end)=0.2*tx(:,size(tx,2)/2:end);
tx2=tx;
tx2(:,1:size(tx,2)/4)=0.25*tx2(:,1:size(tx,2)/4);
tx=conv2(tx,o(5,101)/(5*101),'same');
tx=circshift(tx, [0, -round(size(tx, 2)/3.97)]);
tx2=conv2(tx2,o(5,101)/(5*101),'same');
tx2 = circshift(tx2, [0,-round(size(tx, 2)/2.3)]);
F='FaceC';
T='texturemap';
E='EdgeC';
s(ccy*44-22,ccx*scl,ccz*60-2,tx2,F,T,E,'none');
hold on;
p=plot3(50,0,30,'w.','markersize', 250);
s(ccy*12+33,ccx*scl,ccz*60+10,tx,F,T,E,'none');
s(ccy*12+33-crts(1,end),ccx*scl,ccz*60+10-crts(2,end),tx,F,T,E,'none');
s(ccy*12+33+crts(1,end),ccx*scl,ccz*60+10+crts(2,end),tx,F,T,E,'none');
s(ccy*44-22+crts(1,end),ccx*scl,ccz*60-2+crts(2,end),tx2,F,T,E,'none');
colormap(gray);
hold off;
axis equal off;
set(gcf, 'color', 'k');
camproj p
end
% Now just loop on through the positions, updating the camera position,
% camera target, and camera up-vector
cps=[crts(1,f),0,crts(2,f)];
ctg=cps+[rts(1,f),0,rts(2,f)];
p.ZData=30+crts(2,f);
p.XData=50+crts(1,f);
campos(cps);
camtarget(ctg);
camup(clk(:,f));
camva(95);
end
% Quaternion to directional matrix function
function MT = Q2M(uxyz, ang)
q0 = cos(ang/2);
q = sin(ang/2)*uxyz/norm(uxyz);
MT(:,:) = [1 - 2*q(2)^2 - 2*q(3)^2, 2*q(1)*q(2) - 2*q0*q(3), 2*q(1)*q(3) + 2*q0*q(2);...
2*q(1)*q(2) + 2*q0*q(3), 1 - 2*q(1)^2 - 2*q(3)^2, 2*q(2)*q(3) - 2*q0*q(1);...
2*q(1)*q(3) - 2*q0*q(2), 2*q(2)*q(3) + 2*q0*q(1), 1 - 2*q(1)^2 - 2*q(2)^2];
end
Movie
Audio
This submission does not have audio.