vendredi 27 mai 2016

Why does my matrix rotation not pass my school's unit test?

Basically we were asked to create a matrix calls in C++ for my university course.

To start off, my class uses a column major constructor, but it places it in memory row major:

Matrix2::Matrix2(float R1C1, float R1C2, float R2C1, float R2C2)
{
    //Row major order.
    //Parameters written as column major (a normal matrix) but entered into memory as row major.
    matrix[0] = R1C1;
    matrix[1] = R2C1;
    matrix[2] = R1C2;
    matrix[3] = R2C2;
}

Which I believe is required for the unit test. Matrices are defined as their identity matrix if no parameters are specified.

So, i rotate my matrix with this code:

void Matrix2::setRotateZ(float radians)
{
    (*this) = (*this)*Matrix2(  cosf(radians), -sinf(radians),
                                sinf(radians), cosf(radians));
}

I found this code on wikipedia and on my uni lecture slides. And it seems to go with column major matricies (which is how the data is meant to be input due to my constructor)

Also note that "setRotateZ" should actually be "rotateZ", as it accumulates rotation when called more than once.

My multiplication overload goes like this:

Matrix2 Matrix2::operator*(Matrix2& o)
{
    Matrix2 newMatrix(0.0f, 0.0f, 0.0f, 0.0f);

    newMatrix.matrix[0] = matrix[0] * o.matrix[0] + matrix[2] * o.matrix[1];
    newMatrix.matrix[2] = matrix[0] * o.matrix[2] + matrix[2] * o.matrix[3];
    newMatrix.matrix[1] = matrix[1] * o.matrix[0] + matrix[3] * o.matrix[1];
    newMatrix.matrix[3] = matrix[1] * o.matrix[2] + matrix[3] * o.matrix[3];

    return newMatrix;
}

Which just multiplies like a normal matrix (given that it's row major, 0 is R1C1 and 1 is R2C1 etc)

So pretty much, if I swap:

-sinf(radians)

and

sinf(radians)

in my setRotateZ function above, all works well, the matrix passes all tests including multiplication, rotation and addition.

However, as it is shown now, the matrix fails rotation.

As far as I know, swapping the sign functions should work for row major matrices only, but because mine swaps it in the constructor, entering it as a column major should work.

What am I doing wrong? This is bugging me, even though I've gotten it to work by swapping the values, I want to know what's going on.

I'm pretty much a matrix newb, so a little help will be appreciated!

NOTE: The unit test works by comparing the results of an operation with what they should evaluate to.

Aucun commentaire:

Enregistrer un commentaire