I want to transform geometry from one coordinate system to another. I am given origins and axes of both. I've managed to do so using this method, but I'd like to find one ultimate transformation matrix which would directly transform geometry from one coordinate system to another (which I could also use to e.g easily revert transformation).
I found something about it here and here and it looks like they say that it's impossible. But my English is too weak to be sure if that's the point or even if they talk about problem similar to mine *.*
I'd appreciate any help :)
linear algebra - Transformations between coordinate systems - Mathematics Stack Exchange
linear algebra - How to get the rotation matrix to transform between two 3d cartesian coordinate systems? - Game Development Stack Exchange
rotation matrix between two coordinate systems matlab
Is it possible to find transformation matrix between two coordinate systems?
How do you convert between coordinate systems? What is meant by coordinate transformation? How many types of coordinate transformations exist? Why do we need coordinate transformations? Why are coordinate systems important?
What is the mathematical process involved in the transformation between coordinate systems?
What are the significant applications of transformation between coordinate systems in physics?
Videos
The problem described can be solved as follows. Let
M = m_11 m_12 m_13
m_21 m_22 m_23
m_31 m_32 m_33
denote the desired rotation matrix. We require
1 0 0 * M + t = x_x x_y x_z
0 1 0 y_x y_y y_z
0 0 1 z_x z_y z_y
where t denotes the translation; we see that this matrix equality can be solved by multiplying from the left with the identity matrix, which is the inverse of itself; hence we obtain the following equality.
M + t = x_x x_y x_z
y_x y_y y_z
z_x z_y z_y
This can be rearranged by subtracting t from both sides to obtain the desired matrix M as follows.
M = x_x x_y x_z - t = x_x-t_x x_y-t_y x_z-t_z
y_x y_y y_z y_x-t_x y_y-t_y y_z-t_z
z_x z_y z_y z_x-t_x z_y-t_y z_z-t_z
Note that this was relatively easy as the initial matrix consists out of the basic vectors of the standard base. In general it is more difficult and involves a basis transformation, which basically can be done by Gaussian elimination, but can be numerically difficult.
I think the change of basis could help youWiki Link. Its quite easy to implement.
One easy way is to think of both coordinate systems as transforms from the unit vectors (1,0,0) (0,1,0) and (0,0,1). You start off in this coordinate space (I will call it '1')whose transform matrix is the identity matrix:
[1,0,0]
I = [0,1,0]
[0,0,1]
then your first coordinate space (I will call it '2') has the transform matrix:
[Xx,Xy,Xz]
A = [Yx,Yy,Yz]
[Zx,Zy,Zz]
and your second coordinate space (I will call it '3') has the transform matrix:
[Xx',Xy',Xz']
B = [Yx',Yy',Yz']
[Zx',Zy',Zz']
For your points to be in the first coordinate system, then you have transformed them from 1 to 2. If you want to go from 2 to 3 then you can undo the transform from 1 to 2 then do the transform from 1 to 3. You can reverse the transform by inverting 2's transform matrix.
A point v in 2 can be transformed to a point v' in 3 with this equation: v' = B(A^-1)v where (A^-1) is the inverse of A.
Note this also handles scaling even though you don't need it. This approach will work with translation as well, though you would need a 4x4 matrix instead of a 3x3.
I worked on a project that had lots of transformation to do. I found lots of links on the subject, but they used math that I couldn't comprehend because the symbology was alien. I finally found this paper, which revealed the contents of the matrix to use. The short answer is that the matrix is composed of the dot product of the different axis that you're trying to convert to and from.
In order to save some pain for the next developer I posted some C# in GitHub that has a working sample. The program was derived from one that I found on Code Project, which was written to demonstrate using quaternions but which I found to be useful as a ready-to-go program that would let me rotate and display a surface.
If you want to see what's under the hood here is the essential code. This doesn't show the actual transformation, that's in the code, but the secret sauce of how to do it is located here.
Vector3d X1 = XAxisWorld; // This is vector (1,0,0)
Vector3d X2 = YAxisWorld; // This is vector (0,1,0)
Vector3d X3 = ZAxisWorld; // This is vector (0,0,1)
// These vectors are the local X,Y,Z of the rotated object
Vector3d X1Prime = XAxisLocal;
Vector3d X2Prime = YAxisLocal;
Vector3d X3Prime = ZAxisLocal;
// This matrix will transform points from the rotated axis to the world
LocalToWorldTransform = new Matrix3x3()
{
M11 = (float)Vector3d.DotProduct(X1, X1Prime),
M12 = (float)Vector3d.DotProduct(X1, X2Prime),
M13 = (float)Vector3d.DotProduct(X1, X3Prime),
M21 = (float)Vector3d.DotProduct(X2, X1Prime),
M22 = (float)Vector3d.DotProduct(X2, X2Prime),
M23 = (float)Vector3d.DotProduct(X2, X3Prime),
M31 = (float)Vector3d.DotProduct(X3, X1Prime),
M32 = (float)Vector3d.DotProduct(X3, X2Prime),
M33 = (float)Vector3d.DotProduct(X3, X3Prime),
};
// This matrix will transform points from the world back to the rotated axis
WorldToLocalTransform = new Matrix3x3()
{
M11 = (float)Vector3d.DotProduct(X1Prime, X1),
M12 = (float)Vector3d.DotProduct(X1Prime, X2),
M13 = (float)Vector3d.DotProduct(X1Prime, X3),
M21 = (float)Vector3d.DotProduct(X2Prime, X1),
M22 = (float)Vector3d.DotProduct(X2Prime, X2),
M23 = (float)Vector3d.DotProduct(X2Prime, X3),
M31 = (float)Vector3d.DotProduct(X3Prime, X1),
M32 = (float)Vector3d.DotProduct(X3Prime, X2),
M33 = (float)Vector3d.DotProduct(X3Prime, X3),
};
The text is copied from an archived version of the page originally presented as the answer and that had rot.