2
votes

There is a setRotateM function in android.opengl.matrix package and it

Converts Euler angles to a rotation matrix.

The principal part of the implementation is :

rm[rmOffset + 0]  =   cy * cz;
rm[rmOffset + 1]  =  -cy * sz;
rm[rmOffset + 2]  =   sy;
rm[rmOffset + 3]  =  0.0f;

rm[rmOffset + 4]  =  cxsy * cz + cx * sz;
rm[rmOffset + 5]  = -cxsy * sz + cx * cz;
rm[rmOffset + 6]  =  -sx * cy;
rm[rmOffset + 7]  =  0.0f;

rm[rmOffset + 8]  = -sxsy * cz + sx * sz;
rm[rmOffset + 9]  =  sxsy * sz + sx * cz;
rm[rmOffset + 10] =  cx * cy;
rm[rmOffset + 11] =  0.0f;

rm[rmOffset + 12] =  0.0f;
rm[rmOffset + 13] =  0.0f;
rm[rmOffset + 14] =  0.0f;
rm[rmOffset + 15] =  1.0f;

where cx = cos(angleOnX), sz = sin(angleOnZ) etc.

This bunch of code will give a 4x4 matrix:

[  cy*cz, cx*sz + cx*cz*sy, sx*sz - cz*sx*sy, 0]
[ -cy*sz, cx*cz - cx*sy*sz, cz*sx + sx*sy*sz, 0]
[     sy,           -cy*sx,            cx*cy, 0]
[      0,                0,                0, 1]

While, given rotation matrices around x, y, z axis respectively

Rx = [ 1,  0,   0, 0]
     [ 0, cx, -sx, 0]
     [ 0, sx,  cx, 0]
     [ 0,  0,   0, 1]

Ry = [  cy, 0, sy, 0]
     [   0, 1,  0, 0]
     [ -sy, 0, cy, 0]
     [   0, 0,  0, 1]

Rz = [ cz, -sz, 0, 0]
     [ sz,  cz, 0, 0]
     [  0,   0, 1, 0]
     [  0,   0, 0, 1]

The most similar composition I could find is

(Rx * Ry * Rz)^T = Rz^T * Ry^T * Rx^T = 
[  cy*cz, cx*sz + cz*sx*sy, sx*sz - cx*cz*sy, 0]
[ -cy*sz, cx*cz - sx*sy*sz, cz*sx + cx*sy*sz, 0]
[     sy,           -cy*sx,            cx*cy, 0]
[      0,                0,                0, 1]

Between android's implementation R and raw multiplication Rxyz^T, there are slight differences in R(1,2) R(1,3) R(2,2) R(2,3) components, where cx and sx are switched.

Considering android.opengl.matrix is a widely-applied, time-tested package, I must have done something wrong.

I have two questions: 1. How this difference happens? 2. Why it is (Rx * Ry * Rz)^T? I suppose it was Rz * Ry * Rx

1

1 Answers

-2
votes

question 1: there is only one result in a right handed system using row or column vectors for a particuar order of rotations. so one of the formulas is wrong. maybe you included some terms from the projection matrix.

question 2: it's in x,y,z order because the rotations are done in that order (or the reverse).

the android version's difference might be due to the gui being a left handed system.