I have an object which has a position, a rotation angle and a scale (x and y). The overall transform matrix is as follows :
QTransform xform;
xform.translate(instance.definition.position.x, instance.definition.position.y);
xform.rotateRadians(instance.definition.rotation);
xform.scale(instance.definition.scale.x, instance.definition.scale.y);
I need to scale this object using a global scale which then modifies the local scale of the object. For example, the object is rotated by 45 degrees, I apply a scale of 1,2, I need to know how this affects the local scale as it should affect both local scale axes.
Thanks.
PS : maybe this is impossible due to being a non affine transformation, I don't know, I didn't find much on Google about this particular problem
UPDATE : I think I need to have at least a 3 col by 2 rows matrix transform to keep enough information, I tried some things in SVG which uses this kind of matrix transform and it seems to work, I will need to update this matrix according to the position and rotation though.
Either scale the object first
or calculate the inverse matrix, apply it to object (that undoes the translation/rotation), scale it and apply the first matrix again.
If you take, say, a rectangle, rotate it so that its edges are no longer parallel to the coordinate axes, then apply a scaling factor to, say, X, it will no longer be a rectangle. It will be a parallelogram, and your data structures will have to accommodate more information than they do now.
Related
I'm working in the revitalization of an old 3d game (built using Direct3D) and I'm struggling with the game objects animations.
The game has its objects animations stored in binary files that contains transformation matrices for each bone of its meshes at each frame of the animation (in the form of an array of D3DMATRIX).
I've tried using the D3DXMatrixDecompose function to get the position, rotation and scale but it seems that something is wrong with the animation. Some animations almost matches the originals, but there are some strange rotations in the middle of the animations (the scale vector goes from negative to positive values and that causes the whole bone to rotate in an strange way - it is definitely wrong) and for other animations the whole thing is wrong.
I read somewhere that the function D3DXMatrixDecompose assumes the matrix was composed as a SRT matrix and apparently the order in which each component was combined in the matrix matters. So, as the animations are clearly wrong I'm assuming maybe the matrices were not composed in the SRT order and the output of D3DXMatrixDecompose is wrong.
I didn't find much material to read about this without going very deep on math. As I don't have a strong background on math, hopefully someone can point me in the right direction.
So, how can I decompose position, rotation and scale of an unknown transformation matrix? I'm not asking for a unique algorithm that can do that, I'm asking what I can do in this scenario to find the original (or equivalents) values for the position, rotation and scale of each matrix.
Thanks in advance!
I have an object in 2D space, that is rotated/scaled around. Normally I would find the transformation matrix straightforwardly:
Translate by origin
Rotate
Scale
Translate by -origin
Translate by original position
Given an original object position at (0,0), I can easily get the new location as a vector by multiplying that by the transformation matrix.
However, for this problem I don't have the original position. I only have the final position.
How can I construct the same transformation matrix, when I only have the already-multiplied vector, not the original position?
I still have the transformation point, rotation and scale.
Not sure if I am telling you anything new but you use the inverses of the matrices applied in reverse order to find the original point(s) that was(were) transformed. Not entirely sure that this is what you are looking for but if so then there is a solution below.
Below is an example for 2D transformations. The method is easily extended for 3D
as you know the vector t and the rotation R and the scale s the inverses are easily calculated and applied.
Imagine two coordinate systems layed on top of each other, with a rotation and scale difference between the two:
The problem is to convert a point from the non-rotated system to the other. What we do have, are four corner points forming a rectangle, with coordinates known for both systems at each point. We also know the rotation difference, and I think I at least should know the scale difference too. How do I convert a point from the non-rotated system to the rotated system? I have Unity3D at use.
Extra points for clarity in math :)
PS: I'm writing this really late, going to edit later for more clarity.
Some linear algebra does the trick:
Express each operation as a matrix and matrix multiply those to combine them into a single resulting matrix (for efficiency).
If translation is involved you need to add a dimension to your matrices, see homogenous coordinates.
The reason is that the mappings are affine ones then, not linear ones. You can ignore the extra dimension in the end result. It is just a nice way to embed affine mappings into linear ones, so the algebra is easier.
Example
M = M_trans * M_rot * M_scale
x' = M x
The order here is right to left: vector x is first scaled, then rotated, then translated into vector x'. (Using column vectors).
Hints on the matrices: Rotation Matrix, Scaling Matrix
For deriving 2D formulas when given 3D ones: either keep z = 0 or delete the 3rd row and 3rd column from each matrix.
I have a Bezier path stored as an array of several points, which is each an array of coordinates in the form [cp1x,cp1y,cp2x,cp2y,x,y].
I'd like to be able to scale this path up and down to adjust its size, but I don't know the math to do that. I tried applying a coefficient to each of the coordinate values, but that didn't seem to work.
Does anybody know how to achieve this?
In the standard representation, the points P, represent actual points in space, so you'd move them around like any other points. That is to scale them, just multiple everything by you scaling factor: say it's a, so that would be [a*cp1x,a*cp1y,a*cp2x,a*cp2y,a*x,a*y], or if you want to scale x and y separately, you can use different factors for the x and y components.
Note also that this will scale things relative to the origin (x=0, y=0), so if you don't have any curves at the origin, it can look like a shift. If you want to negate the effect of this shift you can subtract Px and Py from the x and y values respectively, where Px and Py is the point you want to not move when scaled, before you do the scaling (and then add it back after you multiple, if you want to). But if what you want to do is scale an entire canvas, like going from 5x5 inch to 7x7, you'd want to do the multiplication without any shifts (and in this case, by 7./5).
I'm currently working with libQGLViewer, and I'm receiving a stream of data from my sensor, holding azimuth, elevation and roll values, 3 euler angles.
The problem can be considered as the camera representing an aeroplane, and the changes in azimuth, elevation and roll the plane moving.
I need a general set of transformation matrices to transform the camera point and the up vector to represent this, but I'm unsure how to calculate them since the axis to rotate about changes after each rotation ( I think? ).
Either that, or just someway to pass the azimuth, elevation, roll values to the camera and have some function do it for me? I understand that cameraPosition.setOrientation(Quaterion something) might work, but I couldn't really understand it. Any ideas?
For example you could just take the three matrices for rotation about the coordinate axes, plug in your angles respectively, and multiply these three matrices together to get the final roation matrix (but use the correct multiplication order).
You can also just compute a quaternion from the euler angles. Look here for ideas. Just keep in mind that you always have to use the correct order of the euler angles (whatever your three values mean), perhaps with some experimentation (those different euler conventions always make me crazy).
EDIT: In response to your comment: This is accounted by the order of rotations. The matrices applied like v' = XYZv correspond to roation about z, unchanged y and then unchanged x, which is equal to x, y' and then z''. So you have to keep an eye on the axes (what your words like azimuth mean) and the order in which you rotate about these axes.