How to transform coordinates from one cartesian system with given unit vectors to another with different unit vectors?
36 views (last 30 days)
Show older comments
Hello, the problem I am working with is this. I have a set of data points (XYZ format) with unit vectors for the current X, Y, and Z directions. I would like to change this coordinate system to have three different X', Y', and Z' directions. I have a central point, which should be the same in both coordinate systems, as well as the current direction vectors and new vectors.
Old vectors:
vx = [0.8018,0.5913,0.0866]
vy = [0.5948,-0.8037,-0.0192]
vz = [-0.0583,-0.0669,0.9961]
New vectors:
vx' = [1, 0, 0]
vy' = [0, -1, 0]
vz' = [0, 0, 1]
Central Point:
Center = [3.2285, -1.1083, 9.0065]
I tried to use some sort of rotation matrix, but was unsuccesful in applying it.
Thanks!
3 Comments
David Goodmanson
on 30 Jul 2019
Hi Tyler,
this is pretty straightforward once some definitions are established. Suppose p is a point with coordinates x,y,z in the basic coordinate system, and let [x;y;z] form a column vector. I would like to reserve the prime notation for the usual Matlab transpose operation, so suppose the new vectors are called vxnew,vynew,vznew. Then vx',vy',vz' are column vector versions of the original vx,vy,vz. Are you saying that p is the linear combination vx'*X + vy'*Y + vz'*Z?
Answers (1)
Nathan
on 30 Jul 2019
If I understand correctly, you want to rotate the first set of vectors into the second set of vectors, then translate to the new center?
You can translate them by simply adding the center vector after doing the rotation. If what you're looking for is the rotation matrix, there is a very easy way of finding it given that you have three vectors. Your problem is essentially to find a matrix A such that:
[vx_new, vy_new, vz_new] = A * [vx, vy, vz]
Here, vx_new, vy_new, vz_new, vx, vy, and vz are all column vectors. This is equivalent to applying the rotation to the vectors one at a time - grouping any number N of vectors into a 3xN matrix produces a 3xN matrix of rotated vectors. Generally, one would solve this by inverting the matrix [vx, vy, vz], but Matlab allows matrix division, so we can solve this algebraically by "dividing" both sides by the matrix [vx, vy, vz] on the right:
[vx_new, vy_new, vz_new] / [vx, vy, vz] = A * ( [vx, vy, vz] / [vx, vy, vz] )
Thus, A = [vx_new, vy_new, vz_new] / [vx, vy, vz]
In general, for more than 3 vectors, you could in principle do the same thing, but the favored method for estimating a rotation matrix or quaternion is QUEST (QUaternion ESTimator). It finds the optimal attitude quaternion (which you can turn into a rotation matrix) relating the vectors in the unrotated and rotated frames. It looks like you can find implementations of this on the file exchange: https://www.mathworks.com/matlabcentral/fileexchange/65173-absolute-orientation-with-the-quest-algorithm
2 Comments
Nathan
on 2 Aug 2019
Let me make sure I understand correctly: you have 40,000 points in the first frame of reference and you're given the set of orthogonal axis unit vectors in your question, and you want to rotate all of those to the new frame?
You can do that with the same rotation matrix A that solves the rotation of your axis unit vectors. That rotation matrix will rotate any vector into the new frame, not just the axis unit vectors. You can compute A in either of the two ways I mentioned, and then apply it to your vectors (centered at zero first! Translate them with the new origin after rotation!) like this:
First, make sure your vectors are column vectors, concatenated horizontally:
Vectors = ...
[x1 x2 x3 x4 ...;
y1 y2 y3 y4 ...;
z1 z2 z3 z4 ...];
Then, rotate them by multiplying by A on the left:
RotatedVectors = A*Vectors
The RotatedVectors array will be 3 x 40,000, just like the original set of vectors. One note on making the A matrix - the first method that I mentioned using matrix division will produce a matrix that rotates the unit vectors you provided into the new ones, but there is some distortion in that matrix because the vectors you listed only have 4 decimal places of precision. If you test this matrix for orthogonality by multiplying A*A', you will find that you do not get exactly the identity matrix (although you should). Instead, each element of the resulting matrix is "off" from the identity matrix by something on the order of 10^-5. The QUEST method should give you a matrix that is forced to be orthogonal - a true rotation matrix with no distortion. Applying it to the axis unit vectors that you've provided (with only 4 decimals of precision) will not rotate them precisely into your desired frame for the same reason. Errors will be on the order of 10^-5, since that's where your precision is truncated (or rounded). If you have the full precision (15-16 decimal places) values for those vectors, and you can verify that they are precisely orthogonal to each other (dot products are all zero) and have unit length, then I believe both QUEST and matrix division should produce identical results for A.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!