Matrix operator...
Hi
I seemed to have an error in and old code i digged up.
The error was related to the matrix class operator*
and some confusion in which order the operators argument
comes into the function.
Soo please validate what is the correct order of arguments
to a operator when doing matrix multiplication.
for example consider a*b;
Is "this" the left-side (a), and m the right-side (b)
according to the function?
In my previous code I had to reverse the order in
MatrixMultiply, that is exchange arguments this.ref() and m.ref().
So either I didn't understand which arguments was left-/right-side
in the operator or the multiply function was wrong.
If this function below is correct, then the multiply was originally
wrong.
Matrix Matrix::operator*(Matrix &m)
{
Matrix tmp;
MatrixMultiply(tmp.ref(), this->ref(), m.ref());
return tmp;
}
Row-major matrices used by DirectX produces results equal to the left operand followed by the right operand.
Column-major matrices used by OpenGL produce results equal to the right operand followed by the left operand.
There is no right or wrong answer. You have mixed up the major-ness of your matrices. Pick one and stick with it.
L. Spiro
Column-major matrices used by OpenGL produce results equal to the right operand followed by the left operand.
There is no right or wrong answer. You have mixed up the major-ness of your matrices. Pick one and stick with it.
L. Spiro
The result of a matrix multiplication A * B is mathematically defined in explicit terms. You should ever implement the operator w.r.t. that definition, or else confusion will emerge! You should further implement it as non-member function.
Because matrix multiplication isn't commutative, you'll probably come to cases where you don't want to distinct "on the left" or "on the right" (what would simply be possible with operator*) but "on the local side" or "on the global side". Now, here comes the problem of column vs. row vectors into play EDIT, as already mentioned by YogurtEmperor/EDIT. To avoid any confusion, it would IMHO be best to implement 2 non-member functions that explicitely express their behaviour in their names, e.g.
inline Matrix mulWithLocal( Matrix const& matrix, Matrix const& local );
inline Matrix mulWithGlobal( Matrix const& matrix, Matrix const& global );
(Made them inlined to avoid performance penalties.) Then implement the both helper routines w.r.t. the vector convention of your choice utilizing the operator*.
The only issue with the solution above is IMHO that it needs more typing than a simple *.
Just my 2 €-Cent.
[Edited by - haegarr on April 24, 2010 10:43:24 AM]
Because matrix multiplication isn't commutative, you'll probably come to cases where you don't want to distinct "on the left" or "on the right" (what would simply be possible with operator*) but "on the local side" or "on the global side". Now, here comes the problem of column vs. row vectors into play EDIT, as already mentioned by YogurtEmperor/EDIT. To avoid any confusion, it would IMHO be best to implement 2 non-member functions that explicitely express their behaviour in their names, e.g.
inline Matrix mulWithLocal( Matrix const& matrix, Matrix const& local );
inline Matrix mulWithGlobal( Matrix const& matrix, Matrix const& global );
(Made them inlined to avoid performance penalties.) Then implement the both helper routines w.r.t. the vector convention of your choice utilizing the operator*.
The only issue with the solution above is IMHO that it needs more typing than a simple *.
Just my 2 €-Cent.
[Edited by - haegarr on April 24, 2010 10:43:24 AM]
Quote:Original post by haegarrYogurtEmperor was actually referring to matrix majorness (a different issue).
Now, here comes the problem of column vs. row vectors into play, as already mentioned by YogurtEmperor.
Quote:Original post by YogurtEmperorIt sounds like you might be confusing matrix 'majorness' with vector notation convention. When you say (e.g.) 'equal to the left operand followed by the right operand', I assume you mean that the resulting transform is equal to the transform represented by the matrix on the left, followed by the transform represented by the matrix on the right (as would be the case in DirectX). However, this doesn't have anything to do with matrix majorness; rather, it has to do with whether row vectors or column vectors are being used.
Row-major matrices used by DirectX produces results equal to the left operand followed by the right operand.
Column-major matrices used by OpenGL produce results equal to the right operand followed by the left operand.
In any case, this shouldn't have any impact on how the '*' operator is implemented for matrices; matrix multiplication is defined the same way (and should be implemented the same way) regardless of what vector notation convention is being used.
Quote:Original post by jykUhh, I've read it in a hurry. You're right, of course. However,Quote:Original post by haegarrYogurtEmperor was actually referring to matrix majorness (a different issue).
Now, here comes the problem of column vs. row vectors into play, as already mentioned by YogurtEmperor.
Quote:Original post by jykis nevertheless exactly what I meant :)
In any case, this shouldn't have any impact on how the '*' operator is implemented for matrices; matrix multiplication is defined the same way (and should be implemented the same way) regardless of what vector notation convention is being used.
A good way to keep track of this is to wrap your multiplication routine in another named member function, such as Concatenate. Let this function take care of the funny business of matrix multiplication order. This way client code need only worry about which transform should be concatenated, and not the (somewhat arbitrary) way in which this is accomplished.
Quote:for example consider a*b;
Is "this" the left-side (a), and m the right-side (b)
according to the function?
Yes for all operators. a * b is the equivalent of a.operator*(b), so "this" is the left hand side, and the parameter is the right hand side.
Quote:Original post by taz0010Quote:for example consider a*b;
Is "this" the left-side (a), and m the right-side (b)
according to the function?
Yes for all operators. a * b is the equivalent of a.operator*(b), so "this" is the left hand side, and the parameter is the right hand side.
As I suspected, I just forgot the logic around the operators and became unsure whatever was right soo thank you all!
It's been 10 years since I worked with software development before I completely quit coding soo these little things are easy to forget.
My old library routine for matrix multiplication was indeed in the incorrect order, it calculated B*A when it should have calculated A*B (I never tested them when I wrote them a long time ago since I used a sdk at the time).
Once again, thank you all for your help!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement