2013-03-13 2 views
1

андроид использует следующий код для вычисления матрицы вращения:андроида вращение преобразование матрицы

float Ax = gravity[0]; 
float Ay = gravity[1]; 
float Az = gravity[2]; 
final float Ex = geomagnetic[0]; 
final float Ey = geomagnetic[1]; 
final float Ez = geomagnetic[2]; 
float Hx = Ey*Az - Ez*Ay; 
float Hy = Ez*Ax - Ex*Az; 
float Hz = Ex*Ay - Ey*Ax; 
final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 
if (normH < 0.1f) { 
    // device is close to free fall (or in space?), or close to 
    // magnetic north pole. Typical values are > 100. 
    return false; 
} 
final float invH = 1.0f/normH; 
Hx *= invH; 
Hy *= invH; 
Hz *= invH; 
final float invA = 1.0f/(float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 
Ax *= invA; 
Ay *= invA; 
Az *= invA; 
final float Mx = Ay*Hz - Az*Hy; 
final float My = Az*Hx - Ax*Hz; 
final float Mz = Ax*Hy - Ay*Hx; 
if (R != null) { 
    if (R.length == 9) { 
     R[0] = Hx;  R[1] = Hy;  R[2] = Hz; 
     R[3] = Mx;  R[4] = My;  R[5] = Mz; 
     R[6] = Ax;  R[7] = Ay;  R[8] = Az; 
    } else if (R.length == 16) { 
     R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 
     R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 
     R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 
     R[12] = 0;  R[13] = 0;  R[14] = 0; R[15] = 1; 
    } 
} 

Я хотел бы знать, что логика в этом есть. Как использовать акселерометр и магнитометр для получения матрицы вращения?

+0

точная копия вопрос http://stackoverflow.com/questions/15332496/order-of-android -rotation-matrix-conversion/15332763 # 15332763 –

ответ

1

Аннотированный, с угловым случаем, передача удалена:

// Down vector 
float Ax = gravity[0]; 
float Ay = gravity[1]; 
float Az = gravity[2]; 

// North vector 
final float Ex = geomagnetic[0]; 
final float Ey = geomagnetic[1]; 
final float Ez = geomagnetic[2]; 

Н перпендикулярен как Е и А

// H = E x A 
float Hx = Ey*Az - Ez*Ay; 
float Hy = Ez*Ax - Ex*Az; 
float Hz = Ex*Ay - Ey*Ax; 
final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 

Каждый столбец в матрице должен иметь длину 1

// Force H to unit length 
final float invH = 1.0f/normH; 
Hx *= invH; 
Hy *= invH; 
Hz *= invH; 

// Force A to unit length 
final float invA = 1.0f/(float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 
Ax *= invA; 
Ay *= invA; 
Az *= invA; 

Так как A перпендикулярно H, и оба они имеют единичную длину, M также должна иметь единичную длину, поэтому нормализация необходимо здесь.

// M = A x H 
// Forward vector 
final float Mx = Ay*Hz - Az*Hy; 
final float My = Az*Hx - Ax*Hz; 
final float Mz = Ax*Hy - Ay*Hx; 

H, M и А взаимно перпендикулярны, поэтому мы имеем матрицу вращения

R[0] = Hx;  R[1] = Hy;  R[2] = Hz; 
R[3] = Mx;  R[4] = My;  R[5] = Mz; 
R[6] = Ax;  R[7] = Ay;  R[8] = Az; 
+1

Не могли бы вы добавить краткое описание аннотаций вне кода? Это облегчит чтение ответа. – clabacchio

Смежные вопросы