Help multiplying QMatrix4x4 * QVector3D
I don't really understand the behavior of a QMatrix4x4 * QVector3D. I really just want a usable 3x3 matrix. I've figured out that setting the last element (4,4) to 1.0 basically turns QMatrix4x4 into a 3x3, but why is it that this returns inf:
QMatrix4x4 A(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 0.0);
QVector3D B(1.0, 2.0, 3.0);
qDebug() << A*B;@
returns QVector3D(inf, inf, inf).
if (4,4) = 2 the output is QVector3D(1.0, 2.0, 3.0).
if (4,4) = 2 the output is QVector3D(0.5, 1.0, 1.5).
if (4,4) = 0.5 the output is QVector3D(2.0, 4.0, 6.0).
So clearly (4,4) is some kind of inverse length and the last row/column also do some kind of skew or manipulate the geometry somehow.
Any information on this available?
The 4x4 matrix when used with Vector3D in this way represents a compound affine transformation as an augmented matrix. A correct augmented matrix has zeros in the bottom row and right column and 1.0 in the bottom right cell. The input vector is also augmented with an extra 1 to allow matrix multiplication (which would otherwise be impossible).
The three values in the vector resulting from applying the transform are normalised by the value in the additional cell of the augmented vector result:
w = vector.x() * matrix.m +
vector.y() * matrix.m +
vector.z() * matrix.m +
(from src/gui/math3d/qmatrix4x4.h). In your example this evaluates to 0 and dividing by zero gives you infinite rather than an exception.
You want QGenericMatrix:
int n = 0;
for (int r = 0; r < 3; ++r)
for (int c = 0; c < 3; ++c)
m1(r, c) = ++n;
QGenericMatrix<1,3,qreal> m2; m2(0, 0) = 1.0; m2(1, 0) = 3.0; m2(2, 0) = 6.0; QGenericMatrix<1,3,qreal> result = m1 * m2; for (int r = 0; r < 3; ++r) qDebug() << result(r, 0);
Thank you very much. It's much clearer now; I was a bit confused by the GenericMatrix documentation at first. Thanks!
[quote author="klox" date="1358409388"]I was a bit confused by the GenericMatrix documentation at first.[/quote]
You are not alone. Took a while for me to realise the column count came before the row count in the template instantiation.