Search code examples
iphoneopengl-esrotational-matrices

OpenGL : switching and inverting axis


I am working with the gyroscope and obtaining the rotationMatrix that I will use to rotate an object on SceneKit.

That rotation matrix coming from the gyro uses iPhone's axis:

enter image description here

But my application works landscape with the home button left. So, my axis are:

  • x = iphone's Y
  • y = negative iphone's X
  • z = iphone's Z

So, I need to take the rotation matrix I am receiving from the accelerometer that is based on [x,y,z] and create a new one that is [y, -x, -z]... (yes, negative Z because for this particular case I need the object to rotate against Z).

Ok, making it rotate negative is easy but how do I switch the axis X and Y from the original matrix to a new one?

This is what I have so far:

// I create a GLKMatrix4 from the CMRotationMatrix

GLKMatrix4 transform = GLKMatrix4Make(rotMatrix.m11, rotMatrix.m21, rotMatrix.m31, 0.0,
                                      rotMatrix.m12, rotMatrix.m22, rotMatrix.m32, 0.0,
                                      rotMatrix.m13, rotMatrix.m23, rotMatrix.m33, 0.0,
                                      0.0, 0.0,  0.0, 1.0);

GLKMatrix4 negativeX = GLKMatrix4MakeXRotation(-M_PI);
GLKMatrix4 rotate = GLKMatrix4Multiply(transform, negativeX);


GLKMatrix4 negativeZ = GLKMatrix4MakeZRotation(-M_PI);
rotate = GLKMatrix4Multiply(rotate, negativeZ);

// ok, now I have [-x, y, -z]
// how do I switch X and Y and transform that into [y, -x, -z]?

Solution

  • A 3x3 matrix, such as your rotation matrix, is applied as:

    [a b c] [x]    [a*x + b*y + c*z]    x * (a, e, i) +
    [e f g] [y]  = [e*x + f*y + g*z] =  y * (b, f, j) +
    [i j k] [z]    [i*x + j*y + k*z]    z * (c, g, z)
    

    i.e. it is literally three vectors. In your rotMatrix, (m11, m12, m13) is the vector that tells you the direction the transformed x axis will take, (m21, m22, m23) is y and (m31, m32, m33) is z.

    If what you're currently using for the x vector is what you actually want to use for the y value, just swap the columns. If you want to negate one axis, just negate the column.