Tuesday, March 09, 2010

Geometry in 3D: Orthonormal Cartesian basis transformation

Transforming the expression of a vector from one orthonormal Cartesian basis frame cf1 to another orthonormal Cartesian basis cf2, given cf2In1, the expression of basis cf2 in cf1;


Orthonormal transformation is no other than a rotation around the origin (plus possibly some flip of axes);

Suppose
cf2In1 == [c1;c2;c3] == [c1x,c1y,c1z;c2x,c2y,c2z;c3x,c3y,c3z]; % c1,c2,c3 are the basis vectors;
orthonormality requires that

cf2In1 * cf2In1 .' == eye(3) % Identity; because dot(c1,c1) == 1; dot(c1,c2) == 0; etc;


it can be shown, via some straightforward linear algebra, that coordinates expressed in cf1 transformed into cf2 is just

vIn2 == vIn1*tr1To2 == vIn1*(cf2In1.'); % if orthonormality holds, by doing dot product with each axis of cf2In1 we get the transformation here; notice the transposition that makes the dot product appropriate (assume vIn1 being 1 x 3 vector);
On the other hand, if we have coordinates valued in cf2 and want its expression in cf1:

% figure out the inverse transformation;
vIn1 == vIn2*tr2To1 == vIn2*inv(cf2In1.');

however since cf2In1*cf2In1.' == eye(3) we have inv(cf2In1.') == cf2In1;

thus the transformation is simply cf2In1:

vIn1 == vIn2*cf2In1; % tr2To1 == cf2In1;


Some numeric examples:

un = @(x)(x./norm(x)); % make norm 1;
tocol = @(x)(x(:));

% suppose n1 = [1 0 0] and cf1 = eye(3), the default Cartesian frame;

n2 = un(randn(1,3)); % x-direction of cf2In1;

% get cf2In1, using qr;

[cf2In1,r] = qr(tocol(n2)); % r is 3 x 1 with (eigen) values [1;0;0]; cf2In1 are orthonormal basis with first row equal to n2; each row forms one axis of the basis;

% now suppose we have some vector vIn2 that can be expressed as [2 3 4] in cf2; we want to know vIn1, its expression in cf1; intuitively, we can multiply the ratio to each axis in cf2, then find the total projection on coordinate frame 1; which can be expressed as:

vIn2 = [2 3 4]

sum([2*cf2In1(1,:);3*cf2In1(2,:);4*cf2In1(3,:)],1)

% or equivalently

vIn1 = vIn2*cf2In1

% check if this is indeed the answer; find the expression of vIn1 in cf2;

vIn2 = vIn1*(cf2In1.')
Suppose the scenario that v is defined in cf2; we need to express v in cf3In1;

suppose we have cf3In1

[cf3In1,r] = qr(randn(1,3)); % r(1) is also the L2 norm of the random vector;

first express v in cf1;
vIn1 == vIn2*cf2In1;
next express vIn1 in cf3;
vIn3 == vIn1*(cf3In1.');
thus
vIn3 == vIn2*cf2In1*(cf3In1.');
tr2To3 == cf2In1*cf3In1.';
tr2To3 is essentially a rotation from cf2In1 to cf3In1
we established a direct way to get the rotation from cf2In1 to cf3In1:

tr2To3 == cf2In1*cf3In1.';

or from a vector vA to another vector vB all in default coordinate frame 1:

[cfA,~] = qr(vA(:));
[cfB,~] = qr(vB(:));
trAToB = cfA*cfB.';

No comments: