if I do positionVector*worldMatrix the position is transformed into world space.
But what happens if I do it the other way around (worldMatrix*positionVector) in terms of 3d space?
I noticed the result is different to the first one. I already googled about matrix, math they explain a lot but not this one, at least I couldn't find it.
As others have indicated - swapping the order of the multiplication is equivalent to multiplying by the transpose. As it happens, rotation matrices are a special type of matrices known as orthogonal matrices this gets you a number of neat properties.
The most interesting is probably that the transpose of the matrix is its inverse. For your world transform multiplying by the inverse is equivalent to taking a position in world space and pulling it into the local coordinates of the object that transform is associated with.
As an example, consider a box oriented arbitrarily in the world - multiplying by the inverse world transform could (entirely application dependant of course :)) put you in a space where it is axis aligned, and if you were interested in looking for collisions with other objects doing the calculations in the box's local space would make this easier.
In matrixvector, your vector will be interpreted as a column vector. In vectormatrix, it will be interpreted as a row vector. 2x2 examples:
/ a b \ / e \ / ae+bf \
| | * | | = | |
\ c d / \ f / \ ce+df /
/ a b \
( e f ) * | | = ( ea+fc eb+fd )
\ c d /
As you can see, the result is different.
Incidentally, doing the one is the same as doing the other after transposing the matrix.
In terms of 3D space, if you consider one of the two options to be a linear transformation, I don't know if there is any sensible interpretation for the other one. This Wikipedia section says things about it, but it is beyond my understanding of linear algebra.
(matrix * vector) is equivalent to (vector * transpose(matrix))
Matrix math rules:
Given matrices A and B, with sizes MxN and OxP,
The matrix product A * B is only defined if N=O.
The result will be a matrix with size MxP.
Another important rule is that matrix multiplication is not commutative. A * B != B * A
Typically in computer graphics, the position vector is a 4x1 matrix, and the world view matrix is square, 4x4. Thus you should expect that pre-multiplying the world view matrix with the position vector would be undefined. The proper way to apply the world view matrix to the position vector is in the other order, pre-multiplying the position vector with the world view matrix. (I'm speaking mathematically, here)
For more fun with matrix math, check out this tutorial.
Related
I have two tensors of rank 3 each, in other words two 3D matrix. I want to take dot product of these two matrix. I am confused to continue with this problem. Help me out with formula to do so.
A 3-way tensor (or equivalently 3D array or 3-order array) need not necessarily be of rank-3; Here, "rank of a tensor" means the minimum number of rank-1 tensors (i.e. outer product of vectors; For N-way tensor, it's the outer product of N vectors) needed to get your original tensor. This is explained in the below figure of so-called CP decomposition.
In the above figure, the original tensor(x) can be written as a sum of R rank-1 tensors, where R is a positive integer. In CP decomposition, we aim to find a minimum R that yields our original tensor X. And this minimum R is called the rank of our original tensor.
For a 3-way tensor, it is the minimum number of (a1,a2,a3...aR; b1,b2,b3...bR; c1,c2,c3...cR) vectors (where each of the vectors is n dimensional) required to obtain the original tensor. The tensor can be written as the outer product of these vectors as:
In terms of element-wise, we can write the 3-way tensor as:
Now, with that background, to answer your specific question, to take the dot product (also called tensor inner product), both tensors must be of same shape (for e.g. 3x2x5 and 3x2x5), then the inner product is defined as the sum of the element-wise product of their values.
where the script X and Y are the same-shape tensors.
P.S.: The tilde in the above formulae should not be interpreted as an approximation.
The vector inner product sum the elementwise products. The tensor inner product follows the same idea. Match the elements, multiply them, and add them all .
As a background, I'm a computer programmer and I'm working on a software library that allows a computer to quickly search through all dates to find a set of dates that satisfies a criteria. For example:
I want a list of every possible time that has ever occurred that has occurred on a friday or a saturday that is in April or May during the first week of the month.
My library uses numerical sets to efficiently represent ranges of dates that satisfy a criteria.
I've been thinking about ways to improve the performance of some parts of the app and I think that by combining sets and some geometry, I can really improve my results. However, my geometry is a bit rusty and I was hoping you might could help.
Here's my thought:
Certain elements of time can be represented as a circular dial. For example, Minutes can be positioned on a clock with values between 0...59. We could store valid ranges as a list of arcs. For example, If we wanted all times that ended with 05..10, we could store [5,10]. If we wanted all times that end with :45-59 or :00-15, we could store [45, 15]. Notice how this last arc "loops around" the dial. Here's a mockup showing different ranges intersecting on a dial
My question is this:
Given a set of whole numbers between N...M arranged into a circle.
Given Arc1 which is representing by [A, B] and Arc2 which is represented by [C, D] where A, B, C, and D are all within in range N...M
How do I determine:
A. Whether the arcs intersect.
B. If they do, what their intersection is.
C. If they do, what their union is.
Thank you so much for your help. If you're not able to help, if you can point me in the right direction, that would be great.
Thanks!
A simple and safe approach is to split the intervals that straddle 0. Then you perform pairwise interval intersection/union (for instance if A < D and C < B then [max(A,C), min(B,D)] for the intersection), and merge them if they meet at 0.
It seems the primitive operation to implement would be something like 'is the number X contained in the arch [A,B]'. Once you have that, you could implement an [A,B]/[C,D] arch-intersection predicate by something like -
Arch intersection means exactly that at least one of the following conditions is met:
C is contained in [A,B]
D is contained in [A,B]
A is contained in [C,D]
B is contained in [C,D]
One way to implement this contained-in-arch test without any branches is with some trigonometry and vector cross product. Not sure it would be faster (the math/branches performance tradeoff is entirely empiric), but it might be worth a try.
Denote Xa = sin(X/N * 2PI), Ya = cos(X/N * 2PI) and similarly for Xb,Yb etc.
C is contained in [A,B] is equivalent to:
Xa * Yc - Ya * Xc > 0
AND
Xc * Yb - Yc * Xb > 0
You can complete the other 3 conditions in an identical manner.
Hope this turns out useful.
My prof introduced a concept that required use of a vector, which he represented as follows (imagine there is only one pair of brackets below, tall enough to encapsulate both terms; I don't have the rep to paste an image and don't know how to format this otherwise):
v =
[-1/2]
[1/2 ]
One of my personal weaknesses is a lack of familiarity with mathematical notation. Is there an accepted way of interpreting this kind notation? Does it vary by discipline, or is this something generalizable that I really should know? Is there something intrinsic about this notation that would lead one to interpret it differently than if it were written v = [-1/4, 1/4]?
Thanks for the help!
A vector is a one-dimensional matrix, but it is a matrix nonetheless. Writing it out horizontally instead of vertically or vice versa changes the dimensionality of the matrix, changing its meaning among the rest of the equations.
Very often you will "transform" a vector by multiplying them by a matrix. For instance, to rotate a vector, you have to multiply it by the rotation matrix, etc. If your vectors are codified in columns, a multiplication by a matrix M will act from the left, M * v, because of the way the multiplication works (every row of M by the column vector v.) Alternatively, if your vectors are codified as rows (v = [-1/4, 1/4]) the multiplication will act from the right: v * M, again, because of the "row by column" definition of the multiplication of "matrices".
So, it is up to you to represent vectors as rows or columns provided your convention is consistent with the way you multiply them by matrices.
I'm comparing two different linear math libraries for 3D graphics using matrices. Here are two similar Translate functions from the two libraries:
static Matrix4<T> Translate(T x, T y, T z)
{
Matrix4 m;
m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0;
m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0;
m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0;
m.w.x = x; m.w.y = y; m.w.z = z; m.w.w = 1;
return m;
}
(c++ library from SO user prideout)
static inline void mat4x4_translate(mat4x4 T, float x, float y, float z)
{
mat4x4_identity(T);
T[3][0] = x;
T[3][1] = y;
T[3][2] = z;
}
(linmath c library from SO user datenwolf)
I'm new to this stuff but I know that the order of matrix multiplication depends a lot on whether you are using a column-major or row-major format.
To my eyes, these two are using the same format, in that in both the first index is treated as the row, the second index is the column. That is, in both the x y z are applied to the same first index. This would imply to me row-major, and thus matrix multiplication is left associative (for example, you'd typically do a rotate * translate in that order).
I have used the first example many times in a left associative context and it has been working as expected. While I have not used the second, the author says it is right-associative, yet I'm having trouble seeing the difference between the formats of the two.
To my eyes, these two are using the same format, in that in both the first index is treated as the row, the second index is the column.
The looks may be deceiving, but in fact the first index in linmath.h is the column. C and C++ specify that in a multidimensional array defined like this
sometype a[n][m];
there are n times m elements of sometype in succession. If it is row or column major order solely depends on how you interpret the indices. Now OpenGL defines 4×4 matrices to be indexed in the following linear scheme
0 4 8 c
1 5 9 d
2 6 a e
3 7 b f
If you apply the rules of C++ multidimensional arrays you'd add the following column row designation
----> n
| 0 4 8 c
| 1 5 9 d
V 2 6 a e
m 3 7 b f
Which remaps the linear indices into 2-tuples of
0 -> 0,0
1 -> 0,1
2 -> 0,2
3 -> 0,3
4 -> 1,0
5 -> 1,1
6 -> 1,2
7 -> 1,3
8 -> 2,0
9 -> 2,1
a -> 2,2
b -> 2,3
c -> 3,0
d -> 3,1
e -> 3,2
f -> 3,3
Okay, OpenGL and some math libraries use column major ordering, fine. But why do it this way and break with the usual mathematical convention that in Mi,j the index i designates the row and j the column? Because it is make things look nicer. You see, matrix is just a bunch of vectors. Vectors that can and usually do form a coordinate base system.
Have a look at this picture:
The axes X, Y and Z are essentially vectors. They are defined as
X = (1,0,0)
Y = (0,1,0)
Z = (0,0,1)
Moment, does't that up there look like a identity matrix? Indeed it does and in fact it is!
However written as it is the matrix has been formed by stacking row vectors. And the rules for matrix multiplication essentially tell, that a matrix formed by row vectors, transforms row vectors into row vectors by left associative multiplication. Column major matrices transform column vectors into column vectors by right associative multiplication.
Now this is not really a problem, because left associative can do the same stuff as right associative can, you just have to swap rows for columns (i.e. transpose) everything and reverse the order of operands. However left<>right row<>column are just notational conventions in which we write things.
And the typical mathematical notation is (for example)
v_clip = P · V · M · v_local
This notation makes it intuitively visible what's going on. Furthermore in programming the key character = usually designates assignment from right to left. Some programming languages are more mathematically influenced, like Pascal or Delphi and write it :=. Anyway with row major ordering we'd have to write it
v_clip = v_local · M · V · P
and to the majority of mathematical folks this looks unnatural. Because, technically M, V and P are in fact linear operators (yes they're also matrices and linear transforms) and operators always go between the equality / assignment and the variable.
So that's why we use column major format: It looks nicer. Technically it could be done using row major format as well. And what does this have to do with the memory layout of matrices? Well, When you want to use a column major order notation, then you want direct access to the base vectors of the transformation matrices, without having them to extract them element by element. With storing numbers in a column major format, all it takes to access a certain base vector of a matrix is a simple offset in linear memory.
I can't speak for the code example of the other library, but I'd strongly assume, that it treats first index as the slower incrementing index as well, which makes it work in column major if subjected to the notations of OpenGL. Remember: column major & right associativity == row major & left associativity.
The fragments posted are not enough to answer the question. They could be row-major matrices stored in row order, or column-major matrices stored in column order.
It may be more obvious if you look at how a vector is treated when multiplied with an appropriate matrix. In a row-major system, you would expect the vector to be treated as a single row matrix, whereas in a column-major system it would similarly be a single column matrix. That then dictates how a vector and a matrix may be multiplied. You can only multiply a vector with a matrix as either a single column on the right, or a single row on the left.
The GL convention is column-major, so a vector is multiplied to the right.
D3D is row-major, so vectors are rows and are multiplied to the left.
This needs to be taken into account when concatenating transforms, so that they are applied in the correct order.
i.e:
GL:
V' = CAMERA * WORLD * LOCAL * V
D3D:
V' = V * LOCAL * WORLD * CAMERA
However they choose to store their matrices such that the in-memory representations are actually the same (until we get into shaders and some representations need to be transposed...)
How can I turn a regular matrix into a matrix full-ranked in R? Is there an available method for that?
I have a matrix that may have linearly dependent columns and I need to
pass it to a function that requires its argument to be a matrix with
full rank. Since linearly dependent columns are not of interest
anyway, I am looking for a function that removes such columns until
the matrix is full rank. There may be several solutions of course, but
any one of them should be fine.
Right now I am just constructing the matrix column by column and only
add a column if its the resulting matrix is still fullrank, but it
feels like there should be a better way to do this.
Another approach is to minimize |y - Ax|2 + c |x|2,
by tacking an identity matrix on to A and zeros to y.
The parameter c (a.k.a. λ)
trades off fitting y - Ax, and keeping |x| small.
Then run a second fit with the r largest components of x,
r = rank(A) (or any number you please).