Problem
I have a vector field with three dimensions. Each direction of the vector I have to sample seperately and therefore the three grids are slightly unaligned within the measured field (the sample moves, not the measurement grid).
When I realign my measurements my vector components are no longer orthogonal to each other since each has a different transformation. Because the realignment also has a translation, I think each sample point has a slightly different rotation. Basically I want to rotate my sample points but keep my vector directions and make sure they are orthogonal.
Question
How do I correctly 'unrotate' my vectors?
Example
Example MatLab code (note that in my real data I only want to perform the correction in MatLab, I dont perform the transformation in MatLab, just creating fake data to give an example):
n1=10; n2=10; n3=10; %10x10x10 samples for each direction / vector component measurement
sig=5; %smoothness of measured vector field
vec = struct; A = struct; %define structs
%define measurement grid
[vec(1).X,vec(2).X,vec(3).X] = ndgrid(1:n1,1:n2,1:n3); figure;
for itrans = 1:3
vec(itrans).x = imgaussfilt3(rand(n1,n2,n3), sig);%make random smooth vector field
t = rand(1,3); %random translations
r = rand(1,3)*2*pi/50; %random pitch roll yaw
%seperate rotation matrices
R1 = [1, 0, 0;...
0, cos(r(1)), sin(r(1));...
0,-sin(r(1)), cos(r(1))];
R2 = [cos(r(2)), 0,-sin(r(2));...
0, 1, 0;...
sin(r(2)), 0, cos(r(2))];
R3 = [cos(r(3)), sin(r(3)), 0;...
-sin(r(3)), cos(r(3)), 0;...
0, 0, 1];
%make affine component matrices
T = eye(4); T(1,4) = t(1); T(2,4) = t(2); T(3,4) = t(3);%make translation matrix
R = R1*R2*R3; R(4,4) = 1;%combine rotations
S = eye(4); %no skew or scaling
%compose affine transformation
A(itrans).mat = T*R*S;
%apply transformation to coordinates and plot alignment
X = [vec(1).X(:)'; vec(2).X(:)'; vec(3).X(:)';ones(1,numel(vec(3).X))]; XX = A(itrans).mat*X;
subplot(1,3,itrans); scatter3(vec(1).X(:),vec(2).X(:),vec(3).X(:)); hold on; title('displacement measurement 3'); scatter3(XX(1,:)',XX(2,:)',XX(3,:)', 'r'); legend('original', 'displaced')
end
%apply tranformation to data
for itrans = 1:3
vec(itrans).xtrans = interp3(vec(itrans).x ,XX(1,:)',XX(2,:)',XX(3,:)','cubic',0);
end
%plot new vectors
figure; subplot(1,2,1); quiver3(vec(1).X,vec(2).X,vec(3).X,vec(1).x,vec(2).x,vec(3).x); title('original field')
subplot(1,2,2); quiver3(vec(1).X,vec(2).X,vec(3).X,vec(1).xtrans,vec(2).xtrans,vec(3).xtrans); legend('displaced field')
The three realigned coordinates, each component of the vector field has been translated and rotated slightly differently.
The original field, each component of one vector was not really measured at the same location, which I correct for by transforming the coordinates and then interpolating my measurements.
The transformed field, each component of one vector is no longer really along the axis it represents, and they are no longer orthogonal to each other.
Trying to show the problem in 2d with paint. Each arrow shows a measured component, each cross shows a coordinate system. The two blue arrows are the two components that I measure, the two gray arrows are my result after realigning my measurements, the two orange arrows are what I need after somehow 'unrotating' and combining them.
I calculated the displacement for each sampling point
D = X - XX
and then calculated the rotation of that field withcurl()
. That showed a constant rotation for all locations and all directions. So probably I was wrong in assuming that I needed a different correction for each sampling point.Then its probably possible to invert/transpose the rotation matrix and apply it to the measurement (instead of the coordinates of the measurement). Then add the three resulting components of the three measurements together would then give the corrected data.
I added that code to the loop and plotted the displacement and the curl:
Displacement of vectors (color as a function of how close to the edge).
Rotational part of displacement.
Which is equal everywhere:
So I think I can just apply
R'
to each measurement and then add them together as the corrected data.Then just reshape it to an array again.
Now I think the three data sets are aligned and the vector components are orthogonal and aligned with the new coordinate system. Just not sure how to check that. It seems easy to mix up the different components of the measurements and the dimensions of the rotations.