2D rotation matrix applied on 3D points - math

I have rotation matrices, translation vector and a set of 3D categorized points (category depends on the z-coordinates).
One 2x2 rotation matrix M and one 2x1 translation vector T are related to one category.
How can I apply my rotation and translation matrix on each point with coordinate (x, y, z) ?
Is it simply that or I misunderstand the principle of rotation matrix?
add to M a column and a line of 0
add to T a 0 for the z-transformation
then : (x, y, z) = M * (xp, yp, zp) + T

If I understand you correctly you have an affine transformation on R^2 and you want to lift it to an affine transformation on R^3 in such a way that the effect when you apply it to (x,y,z) is to apply the original transformation to (x,y) and leave z unchanged.
If so -- you have to modify your matrix more carefully.
If your original matrix is
M = [a b]
[c d]
Then your new matrix should be
M' = [a b 0]
[c d 0]
[0 0 1]
Note the 1 in the lower right corner -- it is the missing ingredient in the approach that you described. Note that added row and column are the third row and column of the 3x3 identity matrix, which makes sense since you want the result to act like the identity matrix on z. It is easy to work out that
[a b 0] [x] [ax+by]
[c d 0] [y] = [cx+dy]
[0 0 1] [z] [ z ]
Which is what I think you want. (I don't think Stack Overflow has any mark-up for matrices, but my notation should be clear enough)
You are handling T correctly (adding a zero z-component).

Related

Are Geometric Translations Linear?

I'm studying linear algebra and I discovered that linear transformations are often used in video games.
I tried to calculate the associated matrix with the transformation that translates a point (x y z) by a vector (x y z) and I came to the conclusion that that transformation is not linear because, given p1, p2 and a translation vector v ∊ V:
T(v1 + v2) = v1 + v2 + p ≠ T(v1) + T(v2)
I navigated online and I found that 3D coordinates (x y z) are translated in a vector (x y z 1) but, given v1 and v2 ∊ V:
v1 + v2 = (x1 + x2, y1 + y2, z1 + z2, 2)
V is not even a vector space
My question is: why do I get these wrong results?
Thanks for all.
In the vector with homogeneous coordinate format, (x y z 1),
(x/1 y/1 z/1) are 3D cartesian coordinates, and 1 is the scaling factor.
We divide the first three values by the scaling factor to get the vector in cartesian coordinate format, (x y z). Homogeneous coordinates can be useful for efficient arbitrary precision with rational coordinates, and eloquent algebra with nice properties like linearity here.
When we want to translate a point by adding a vector, that's natural with cartesian coordinates. With all point/vector coordinates in cartesian format,
addition of a vector, v, to a point, p1, is a translation, T1, to some point, p2, such that
T1(p1) = p1 + v = p2
You are correct that something like T1 isn't linear.
When we want to translate a point by multiplying a matrix, it's more natural to think in homogeneous coordinates. This matrix, A, would be the identity matrix, but its last column is the vector, v, in homogeneous form. With points in homogeneous format, we can represent the transform, T2, as
T2(p1) = A * p1 = p2
With T2, we do have a linear transform.
Your results after not wrong: The translation of a point by a vector is not a linear transformation.
Translating a point by a vector is an affine transformation and it's done in an affine space. An affine space can be loosely defined as a set of points together with a vector space, where you can add a vector to a point and get another point as a result. Adding points to points is not allowed.
One way to construct an affine space is by taking a projective space whose elements are represented with homogeneous coordinates. These concepts come from the beautiful field of projective geometry, but a full explanation does not fit in a stack overflow post.
A more direct way to construct an affine space is by taking a vector space and adding one extra bit of information: take vectors of the form (x y z 1) as the points, and vectors of the form (x y z 0) as the vectors. Note that the points do not form a vector space, but the vectors do, and that if you add a vector to a point, the result is another point.
With this representation of points and vectors, translation of a point p by a vector can be written as a matrix multiplication T*p. The matrix T for translating by vector (x y z 0) is:
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
Note that this is still not a linear transform because points do not form a vector space.

Derive Rigid Transform Matrix from Axes and Origin

I'm trying to derive the matrix of a rigid transform to map between two coordinate spaces. I have the origin and the axis directions of the target coordinate space in terms of the known coordinate space; does anyone know how I can solve for the 4x4 rigid transformation matrix given these?
So, in other words, I have two coordinate spaces, A and B, and I know
Point3D originOfBInA;
Vector3D xAxisOfBInA; // Unit vector
Vector3D yAxisOfBInA; // Unit vector
Vector3D yAxisOfBInA; // Unit vector
And I'm trying to find the 4x4 matrix
Matrix4x4 AtoB;
First construct the 4x4 matrix for the change of basis (call it M) by using your unit vectors (Ax, Ay, Az) and the origin (T) as column vectors:
M =
[Ax Ay Az T] <-- 3x4
[0 0 0 1]
To transform the coordinates of a point p (specified with respect to frame A) to q (with respect to frame B), just multiply by the inverse of M:
q = M-1p

Rotation matrix openCV

I would like to know how to find the rotation matrix for a set of features in a frame.
I will be more specific. I have 2 frames with 20 features, let's say frame 1 and frame 2. I could estimate the location of the features in both frames. For example let say a certain frame 1 feature at location (x, y) and I know exactly where it is so let's say (x',y').
My question is that the features are moved and probably rotated so I wanna know how to compute the rotation matrix, I know the rotation matrix for 2D:
But I don't know how to compute the angle, and how to do that? I tried a function in OpenCV which is cv2DRotationMatrix(); but the problem which as I mentioned above I don't know how to compute the angle for the rotation matrix and another problem which it gives 2*3 matrix, so it won't work out cause if I will take this 20*2 matrix, (20 is the number of features and 2 are the location in (x,y)) and multiply it by the matrix by 2*3 which is the results from the function then I will get 20*3 matrix which it doesn't seem to be realistic cause I'm working with 2D.
So what should I do? To be more specific again, show me how to compute the angle to use it in the matrix?
I'm not sure I've understood your question, but if you want to find out the angle of rotation resulting from an arbitrary transform...
A simple hack is to transform the points [0 0] and [1 0] and getting the angle of the ray from the first transformed point to the second.
o = M • [0 0]
x = M • [1 0]
d = x - o
θ = atan2(d.y, d.x)
This doesn't consider skew and other non-orthogonal transforms, for which the notion of "angle" is vague.
Have a look at this function:
cvGetAffineTransform
You give it three points in the first frame and three in the second. And it computes the affine transformation matrix (translation + rotation)
If you want, you could also try
cvGetPerspectiveTransform
With that, you can get translation+rotation+skew+lot of others.

How to represent a 4x4 matrix rotation?

Given the following definitions for x,y,z rotation matrices, how do I represent this as one complete matrix? Simply multiply x, y, & matrices?
X Rotation:
[1 0 0 0]
[0 cos(-X Angle) -sin(-X Angle) 0]
[0 sin(-X Angle) cos(-X Angle) 0]
[0 0 0 1]
Y Rotation:
[cos(-Y Angle) 0 sin(-Y Angle) 0]
[0 1 0 0]
[-sin(-Y Angle) 0 cos(-Y Angle) 0]
[0 0 0 1]
Z Rotation:
[cos(-Z Angle) -sin(-Z Angle) 0 0]
[sin(-Z Angle) cos(-Z Angle) 0 0]
[0 0 1 0]
[0 0 0 1]
Edit: I have a separate rotation class that contains an x, y, z float value, which I later convert to a matrix in order to combine with other translations / scales / rotations.
Judging from the answers here, I can assume that if I do something like:
Rotation rotation;
rotation.SetX(45);
rotation.SetY(90);
rotation.SetZ(180);
Then it's actually really important as to which order the rotations are applied? Or is it safe to make the assumption that when using the rotation class, you accept that they are applied in x, y, z order?
Yes, multiplying the three matrices in turn will compose them.
EDIT:
The order that you apply multiplication to the matrices will determine the order the rotations will be applied to the point.
P × (X × Y × Z) Rotations in X, Y, then Z will be performed
P × (Y × X × Z) Rotations in Y, X, then Z will be performed
P × (Z × X × Y) Rotations in Z, X, then Y will be performed
It actually is really important what order you apply your rotations in.
The order you want depends on what you want the rotations to do. For instance, if you are modeling an airplane, you might want to do the roll first (rotate along the long axis of the body), then the pitch (rotate along the other horizontal axis), then the heading (rotate along the vertical axis). This would be because, if you did the heading first, the plane would no longer be aligned along the other axes. Beyond that, you need to deal with your conventions: which of these axes correspond to X, Y, and Z?
Generally, you only want to choose a particular rotation order for specific applications. It doesn't make much sense to define a generic "XYZrotation" object; typically, you will have generic transformations (i.e., matrices that can be any concatenation of rotations, translations, etc.) and various ways to get them (e.g., rotX, rotY, translate, scale...), plus the ability to apply them in a particular order (by doing matrix multiplication).
If you want something that can only represent rotations and nothing else, you might consider quaternions (as anand suggests). However, you still need to decide which order to perform your rotations in, and, again, it doesn't really make sense to hardwire a required order for that.
As an aside and if you're early enough in your development activities here, you might want to consider using quaternion rotation. It has a number of comparative advantages to matrix based approaches.

Given vector of one axis, how do I find vectors of other two axes?

This is a maths problem I am not exactly sure how to do. The vector is not aligned to an axis, so just rotating 90 degrees around x, y or z won't necessarily give me the other axes.
I can think of a couple of different scenarios you might be asking about.
Given: A pre-existing coordinate system
In a 2D system, your axes/basis are always [1,0] and [0,1] -- x and y axes.
In a 3D system, your axes/basis are always [1,0,0], [0,1,0], and [0,0,1] -- x, y, and z.
Given: One axis in an arbitrary-basis 2D coordinate system
If you have one axis in an arbitrary-basis 2D coordinate system, the other axis is the orthogonal vector.
To rotate a vector orthogonally counter-clockwise:
[x_new, y_new] = [ -y_old, x_old]
To rotate a vector orthogonally clockwise:
[x_new, y_new] = [ y_old, -x_old]
To summarize:
Given: x-axis = [ a, b]
Then: y-axis = [-b, a]
Given: y-axis = [ c, d]
Then: x-axis = [ d, -c]
Given: Two axes in an arbitrary-basis 3D coordinate system
To do this, find the cross product.
[a,b,c] x [d,e,f] = [ b*f - c*e, c*d - a*f, a*e - b*d ]
Following these three guidelines:
(x axis) x (y axis) = (z axis)
(y axis) x (z axis) = (x axis)
(z axis) x (x axis) = (y axis)
Given: One axis in an arbitrary-basis 3D coordinate system
There is not enough information to find the unique solution this problem. This is because, if you look at the second case (One axis in an arbitrary-basis 2D coordinate system), you first need to find an orthogonal vector. However, there are an infinite amount of possible orthogonal vectors to a single axis in 3D space!
You can, however, find one of the possible solutions.
One way to find an arbitrary one of these orthogonal vectors by finding any vector [d,e,f] where:
[a,b,c] = original axis
[d,e,f] = arbitrary orthogonal axis (cannot be [0,0,0])
a*d + b*e + c*f = 0
For example, if your original axis is [2,3,4], you'd solve:
2 * d + 3 * e + 4 * f = 0
That is, any value of [d,e,f] that satisfies this is a satisfactory orthogonal vector (as long as it's not [0,0,0]). One could pick, for example, [3,-2,0]:
2 * 3 + 3 *-2 + 4 * 0 = 0
6 + -6 + 0 = 0
As you can see, one "formula" that works to is [d,e,f] = [b,-a,0]...but there are many other ones that can work as well; there are, in fact, an infinite!
Once you find your two axes [a,b,c] and [d,e,f], you can reduce this back to the previous case (case 3), using [a,b,c] and [d,e,f] as your x and y axes (or whatever axes you need them to be, for your specific problem).
Normalization
Note that, as you continually do dot products and cross products, your vectors will begin to grow larger and larger. Depending on what you want, this might not be desired. For example, you might want your basis vectors (your coordinate axes) to all be the same size/length.
To turn any vector (except for [0,0,0]) into a unit vector (a vector with a length of 1, in the same direction as the original vector):
r = [a,b,c]
v = Sqrt(a^2 + b^2 + c^2) <-- this is the length of the original vector
r' = [ a/v , b/v , c/v ]
Where r' represents the unit vector of r -- a vector with length of 1 that points in the same direction as r does. An example:
r = [1,2,3]
v = Sqrt(1^2 + 2^2 + 3^2) = Sqrt(13) = 3.60555 <-- this is the length of the original vector
r' = [0.27735, 0.55470, 0.83205]
Now, if I wanted, for example, a vector in the same direction of r with a length of 5, I'd simply multiply out r' * 5, which is [a' * 5, b' * 5, c' * 5].
Having only one axis isn't enough, since there are still an infinite number of axes that can be in the perpendicular plane.
If you manage to get another axis though, you can use the cross product to find the third.
If you have one vector (x,y,z) you can get one perpendicular vector to it as (y,-x,0) (dot-product is xy-yx+0*z = 0)
Then you take the cross-product of both to get the remaining perpendicular vector:
(x,y,z) × (y,-x,0) = (0y+zx, yz-0x, -x²-y²) = (zx, yz, -x²-y²)
Are you talking about a typical 3coordinate system like the one used in a 3D engine?
With just a vector you can't find the other two, the only information you will have it the plane on which they lay.. but they can be at any angle also if they're perpendicular with the only one vector you have.

Resources