I have a basic question which i am not able to figure out. Can any one help me to understand how scale and rotation is calculated from the transformation matrix (in nvidia scenix graph).
For example i have a matrix:
{
1 , 0.5 , 0.5 , 100
0.5, 1 , 0.5 , 20
0.5, 0.5 , 1 , 30
0, 0 , 0, 1
}
From above matrix i know that translation is 100,20,30 and centre is 0,0,0.
I am not sure of scaling and rotation.
Thanks
Related
I work on a tool to convert old 3d data from a program and convert it into a new format.
The problem i have is, the old program is storring the scale/rotation in a 3x3 matrix and i have no experiance with this kind of stuff.
For testing i have created an object only with scale 0.5 and saved it. It has the matrix
0.5, 0.0, 0.0
0.0, 0.5, 0.0
0.0, 0.0, 0.5
These are the scales for all 3 axis
Then i changed the object to have only rotations xyz of 45 degrees and a scale of 1 and got this matrix
0.5, -0.146447, 0.853553
0.5, 0.853553, -0.146447
-0.707107, 0.5, 0.5
I was able to convert this to the correct angles
Now i come to my showstopper: i changed the object to have a scale of 0.5 and a rotation of 45 degrees. The new matrix somehow combined both values into one matrix:
0.25, -0.0732233, 0.426777
0.25, 0.426777, -0.0732233
-0.353553, 0.25, 0.25
Basically the vales are the half of the secound matrix.
Currently im not able to figure out how to get the scale and the rotation out of this matrix, basically seperate them from each other. So if someone has an idea how this has to be done it world be great.
The determinant of the matrix expresses the factor by which volumes increase. If you're matrix preserves angles, then that determinant must be the third power of the scale factor. Take the cube root and you get the scale factor.
Divide all elements of the matrix by that factor and you should end up with a pure rotation, or mathematically speaking an orthogonal matrix. Wikipedia has a good article on how to convert between that and various other formalisms.
I want to found the endpoints (X,Y,Z) coordinatas of yellow vector.
In two dimension is very simple, but i want to rotate 45 degrees around Z axis in 3D
in 2D:
lenght: 10
start point: 0, 0
end point X=lenght*COS(45deg)=7,07
end point Z=lenght*SIN(45deg)=7,07
How do i calculate X,Y,Z endpoints in 3D?
step, yellow vector end position in 10,0,0 ->
step, increment degrees from X axis, +45 degrees ->
step rotate the vector endpoint around Z axis with +45 degrees, what is the vector new endpoint coordinatas?
You use some unconventional terminology. Particularly it is not clear what "increment degrees from X axis, +45 degrees" means. Anyway this is probably solvable with rotation matricies. I assume that step #2 means "rotate along the Y-axis by 45 degrees".
So this gives us:
Step 1 v1 = (10,0,0)
Step 2 rotate along the Y-axis by 45 degrees. So we should multiply our vector by a matrix:
cos(45) 0 sin(45)
0 1 0
-sin(45) 0 cos(45)
which gives us v2 = (10*sqrt(2)/2, 0, 10*sqrt(2)/2) = (5*sqrt(2), 0, 5*sqrt(2))
Step 3 rotate the vector endpoint around Z axis with +45 degrees. So we should multiply our vector v2 by a matrix:
cos(45) -sin(45) 0
sin(45) cos(45) 0
0 0 1
which gives us v3 = (5, 5, 5*sqrt(2)).
P.S. Note that by doing those 2 rotations you don't get the "middle line" of the 3 axis as one might think, because that vector obviously has all 3 components equal.
I tried Euler angles transformation in this case, but I could not find the correct sequence of xyz to get target orientation.
P.S. I am following the convention of x->y->z for Euler angles transformation.
P.S. Euler angles transformation: each rotation takes place relative to original frame.
The rotation of z axis can only switch y and x, but it won't lead to final target.
What is the right way?
final answer:
#Rooscannon, thanks you very much!
Rotate (45, 180 , 90)
Here the maths
http://www.staff.city.ac.uk/~sbbh653/publications/euler.pdf
getting the rotation matrix is very simple in your use case. The columns of the 3X3 rotation matrix are the rotated unit vectors x,y,z in the new position. For example x was originally (1,0,0) and after rotation (0,-1,0). y = (-sqrt(2)/2, 0, -sqrt(2)/2), z = ( sqrt(2)/2, 0, -sqrt(2)/2).
So your rotation matrix will be something like
0 -0.7 0.7
R = -1 0 0
0 -0.7 -0.7
Use exact values though. If insecure the determinant should be 1 and the norm of each column and row should be 1.
Rotate 135 on y. And then rotate -90 on z to get the desired angel.
Your final rotation will be :
(0,135,-90)
Hope this helps.
What I am trying to achieve here is to convert the rotation Matrix from one software (Quest3D) to an another one (Rock robotic framework) of course with different reference system.
I have the Motion matrix (the 4x4 matrix which contains the 3x3 rotation matrix and the translation vector) in a Left-Handed (LH for the following) system as follow :
X positive forward
y positive up
z positive left
And I would like to put it in an Right-Handed (RH for the following) system as follow :
(edit)
North West Up (NWU):
X positive forward
y positive **left**
z positive up
This is what I tried to find so far and I will be glad if someone could help me there or point me to some documentations that I could have missed !
First step: the order of rotations
So first of all, to find the theoretical rotation matrix of Quest3D I needed to know what was the order of multiplication that creates the rotation matrix with an euler angle notation.
With the following reference system
I have :
Rx_LH(tet1) =
[ 1, 0, 0 ]
[ 0, cos(tet1), -sin(tet1)]
[ 0, sin(tet1), cos(tet1)]
Ry_LH(tet2) =
[ cos(tet2), 0, sin(tet2)]
[ 0, 1, 0 ]
[ -sin(tet2), 0, cos(tet2)]
Rz_LH(tet3) =
[ cos(tet3), -sin(tet3), 0]
[ sin(tet3), cos(tet3), 0]
[ 0, 0, 1]
Then since there is 12 different way of computing the rotation matrix, I wrote a small matlab program that computes all the different options and then with a set of specified values for X,Y,Z in Quest3D (See image here) and the corresponding matrix in numerical values I tried to match which one of the rotation matrix is the same and therefore I will have my rotation order.
Result : not so much.. I manage to have a matrix that posses the same element but not at the right position in the matrix. ( there is actually a symmetry regarding the diagonal)
This is my "target matrix"
MatR_Sim_LH =
0.9447 0.3130 -0.0978
-0.0290 0.9363 0.1987
0.1538 -0.1593 0.9752
and this is the closest thing I have
0.9447 -0.2896 0.1538
0.3130 0.9363 -0.1593
-0.0978 0.1987 0.9752
Let's say it's a mistake of mine, the order to create the rotation matrix is 213.
Change of basis
For the change of basis I have to go from the Quest3D reference system to a
** Right-Handed with X positive forward, y positive right and z positive Up **.
My idea was the following.
a) change from Left-Handed to Right-Handed
b) Do what's necessary to the motion matrix when we swap the Y and Z axis in the reference frame.
for a) I am using this matrix
Switch_LH2RH =
1 0 0
0 1 0
0 0 -1
which I apply to my LH (Left-Handed) rotation matrix of Quest3D like this
MatR_Sim_RH = Switch_LH2RH * MatR_Sim_LH * Switch_LH2RH;
then for b) to switch Y and Z I am using the following matrix in the following expression
Mat_toggle_ZY =
1 0 0
0 0 1
0 1 0
MatR_Rock_RH = Mat_toggle_ZY * MatR_Sim_RH * Mat_toggle_ZY;
But of course it's not working for some reason that probably are not obvious for me yet !
Thanks for the help
V.v
I have two squares, S1 = (x1,y1,x2,y2) and S2 = (a1,b1,a2,b2)
I'm looking for the A transformation matrix with which
A * S1 = S2
As far as I see, A is an affine 3x3 matrix, so I have 9 unknown values.
How can I calculate these values?
thanks and best,
Viktor
There are really only four unknown values here. A rotation angle, a scale factor and an x and y translation. Of your three by three matrix the bottom row is always 0,0,1 which reduces you to six unknowns. The right hand column will be Tx,Ty,1 which are your translations (and the 1 we already know about).
The two by two "matrix" left will be your rotation and scaling. This will (off the top of my head) be something like:
ACos(B), -Asin(B)
ASin(B), aCos(B)
So in total:
ACos(B), -Asin(B), Tx
ASin(B), ACos(B), Ty
0 , 0 , 1
You extend your co-ordinate matrices with the 1 on the end of each co-ordinate to give 2x3 matrices and they then multiply to give you the four equations you need to solve for the four variables. That is left as an exercise for the reader.
A transformation matrix is a factor of scaling matrix Ss, transition matrix St and rotation matrix Sr.
Assume the old point is Po is (Xo,Yo) and as vector will be represented as (Xo Yo 1)' same for the new point Pn
Then Pnv =SsStSrPov
Where Sx is
Sx 0 0
0 Sy 0
0 0 1
St is
1 0 Tx
0 1 Ty
0 0 1
Sr is
Cos(th) -Sin(th) 0
Sin(th) Cos(th) 0
0 0 1
Now back to your question. if two point are giving to represent a rectangle we can just find the parameter of two matrix and the third one will be an identity matrix.
Rect1 is represented as Top-Left point P11 and Bottom-Right Point P12
Rect2 is represented as Top-Left point P21 and Bottom-Right Point P22
S=Ss*St
Sx 0 Tx
0 Sy Ty
0 0 1
Now you have 4 missing parameters and 4 set of equations
P21=S*P11
P22=S*P12
X[P21] =Sx*X[P11]+Tx
Y[P21] =Sy*Y[P11]+Ty
X[P22] =Sx*X[P12]+Tx
Y[P22] =Sy*Y[P12]+Ty
Solve it and you'll get your answer.
and if you have transition and rotation then
S=Sr*St.
Cos(th) -Sin(th) Tx
Sin(th) Cos(th) Ty
0 0 1
Now you have 3 missing parameters and 4 set of equations
P21=S*P11
P22=S*P12
X[P21] =Cos(th)*X[P11]-Sin(th)*Y[P11]+Tx
Y[P21] =Sin(th)*X[P11]+Cos(th)*Y[P11]+Ty
X[P22] =Cos(th)*X[P11]-Sin(th)*Y[P12]+Tx
Y[P22] =Sin(th)*X[P11]+Cos(th)*Y[P12]+Ty
Replace Cos(th) with A and Sin(th) With B and solve the equations.
X[P21] =A*X[P11]-B*Y[P11]+Tx
Y[P21] =B*X[P11]+A*Y[P11]+Ty
X[P22] =A*X[P11]-B*Y[P12]+Tx
Y[P22] =B*X[P11]+A*Y[P12]+Ty
Check if its correct A^2+B^2 =? 1 if is true then th = aCos(A)
The last part of the solution, if you'll have all three matrixes, then S=SrStSs is
Sx*sin(th) -Sx*cos(th) Tx
Sy*cos(th) Sy*sin(th) Ty
0 0 1
Now we have 5 missing variables and we need 6 different set of equations to solve it. which is mean 3 points from each rectangle.
You shouldn't have a 3x3 matrix if you're just looking to transform a 2D object. What you're looking for is a 2x2 matrix that solves A*S1=S2. This can be done in many different ways; in MATLAB, you'd do a S2/S1 (right matrix division), and generally this performs some kind of Gaussian elimination.
How can I calculate these values?
When applied to 2d/3d transformations, matrix can be represented a coordinate system, unless we are talking about projections.
Matrix rows (or columns, depending on notation) form axes of a new coordinate system, in which object will be placed placed if every object vertex is multiplied by the matrix. Last row (or columne, depending on notation) points to the center of the new coordinate system.
Standard OpenGL/DirectX transformation matrix (NOT a projection matrix):
class Matrix{//C++ code
public:
union{
float f[16];
float m[4][4];
};
};
Can be represented as combination of 4 vectors vx (x axis of the new coordinate system), vy(y axis of a new coordinate system), vz(z axis of a new coordinate system), and vp (center of the new system). Like this:
vx.x vx.y vx.z 0
vy.x vy.y vy.z 0
vz.x vz.y vz.z 0
vp.x vp.y vp.z 1
All "calculate rotation matrix", "calculate scale matrix", etc go down to this idea.
Thus, for 2d matrix, you'll have 3x3 matrix that consists of 3 vectors - vx, vy, vp, because there is no z vector in 2d. I.e.:
vx.x vx.y 0
vy.x vy.y 0
vp.x vp.y 1
To find a transform that would transform quad A into quad B, you need to find two transforms:
Transform that will move quad A into origin (i.e. at point zero), and convert it into quad of fixed size. Say, quad (rectangle) whose one vertex x = 0, y = 0, and whose vertices are located at (0, 1), (1, 0), (1, 1).
Transform that turns quad of fixed size into quad B.
You CANNOT do that it this way if opposite edges of quad are not parallel. I.e. parallelograms are fine, but random 4-sided polygons are not.
A quad can be represented by base point (vp) which can be any vertex of the quad and two vectors that define quad sizes (direction of the edge multiplied by edge's length). I.e. "up" vector and "side" vector. Which makes it a matrix:
side.x side.y 0
up.x up.y 0
vp.x vp.y 1
So, multiplying a quad (vp.x = 0, vp.y = 0, side.x = 1, side.y = 0, up.x = 0, up.y = 1) by this matrix will turn original quad into your quad. Which means, that in order to transform
quad A into quad B, you need to do this:
1) make a matrix that would transform "base 1unit quad" into quad A. Let's call it matA.
2) make a matrix that would transform "base 1 unit quad" into quad B. let's call it matB.
3) invert matA and store result into invMatA.
4) the result matrix is invMatA * matB.
Done. If you multiply quad A by result matrix, you'll get quad B. This won't work if quads have zero widths or heights, and it won't work if quads are not parallelograms.
This is hard to understand, but I cannot to make it simpler.
What do you mean by S1 = (x1,y1,x2,y2)?
Do they represent the top-left and bottom-right corners of the square?
Also, can you guarantee there's only rotation between the squares or do you need a full affine transformation which allows for scaling, skewing, and translation?
Or do you also need a perspective transformation?
Only if it's a perspective transformation, will you need 3x3 matrix with 8 dof as you've mentioned in your post.