0

How can I check if a matrix is axis aligned? Therefor I mean any rotation a multiple of 90 degrees (including 0).

Right now the best I came up with is creating 2 points that are axis aligned, pass them through the matrix and see if the points are still axis aligned.


// return 0, 90, 180 or 270 if axis aligned, else returns -1
static public int test_matrix_axis_aligned(Mat3 m) {

    int rot = -1;

    Vec2 a = create_vec2(0, 0);
    Vec2 b = create_vec2(1000, 0);

    a = mult(m, a);
    b = mult(m, b);

    // TODO rounding with a certain threshold?
    a.x = round(a.x);
    a.y = round(a.y);
    b.x = round(b.x);
    b.y = round(b.y);

    boolean axis_aligned = a.x == b.x || a.y == b.y;

    if (axis_aligned) {

        //float angle = atan2(b.y - a.y, b.x - a.x);
        //println("a: "+angle);
        //if (angle < 0) angle += PI; // wrong for 270
        //rot = (int) round(degrees(angle));

        float dx = a.x - b.x;
        float dy = a.y - b.y;

        if (dx < 0 && dy == 0) {
            rot = 0;
        } else if (dx == 0 && dy < 0) {
            rot = 90;
        } else if (dx > 0 && dy == 0) {
            rot = 180;
        } else if (dx == 0 && dy > 0) {
            rot = 270;
        }

    }

    return rot;
}

But I wonder if it can be done more efficient.

George Profenza
  • 50,687
  • 19
  • 144
  • 218
clankill3r
  • 9,146
  • 20
  • 70
  • 126
  • 2
    `Vec2` means you're working in 2D? Because that greatly simplifies things. If you exclude scaling and mirroring, there are only 4 matrices which perform a rotation. You can just test if your matrix is exactly one of those four. – MSalters Jun 18 '19 at 08:58
  • Being axis-aligned does not imply that the transformation is a rotation. As said in a previous comment, nonuniform scaling and reflections can have the same effect. I mention it because it makes your question ambiguous. The title says "axis-aligned" but the description says "rotation of 90 degrees". It's a subtle but important difference to get a correct solution for your problem. – Gilles-Philippe Paillé Jun 18 '19 at 14:46

2 Answers2

0

If you have components of affine matrix that might be composed from translation, scale and rotation, then you can extract rotation angle as

 fi = atan2(-m12, m11)

where m11 and m12 are the first and the secons components of the first matrix row (note than matrices might be left-handed and right handed, so you perhaps would need to use column rather then row)

Addition: Something similar

MBo
  • 77,366
  • 5
  • 53
  • 86
0

If you want a routine that will work in any number of dimensions, you could do two steps.

  1. Check that each row (or column) contains all zeros except for one number which is either 1 or -1. If you want to allow scaling in your "rotations" this number could be any non-zero value.
  2. Check that the determinant of the matrix is 1. If you want to allow reflections in your "rotations" you would also allow allow a determinant of -1. If you want to allow scaling in your "rotations" you allow any non-zero determinant.

As a comment said, your job is easier if you know your matrix has only two dimensions.

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50