Hinweis:
Mithilfe von transponierten Matrizen lassen sich Rotationstransformationen wieder rückgängig machen. Bewirkt eine Rotationsmatrix beispielsweise eine Drehung von 10° um die x-Achse, so bewirkt die transponierte Rotationsmatrix eine Drehung von –10° um dieselbe Achse. Eine invertierte Rotationsmatrix hätte zwar denselben Effekt, jedoch ist der Berechnungsaufwand für eine inverse Matrix deutlich höher. Sollen jedoch Rotations-Translations-Transformationen rückgängig gemacht werden, dann kommt man um die Verwendung der inversen Matrix nicht herum.
transponierte Matrix
INLINE D3DXMATRIX* D3DXMatrixTranspose(D3DXMATRIX *pOut,
CONST D3DXMATRIX *pM)
{
int i,j;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
pOut->m[i][j] = pM->m[j][i];
}
}
return pOut;
}
CONST D3DXMATRIX *pM)
{
int i,j;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
pOut->m[i][j] = pM->m[j][i];
}
}
return pOut;
}
inverse Matrix
INLINE D3DXMATRIX* D3DXMatrixInverse(D3DXMATRIX *pOut,
FLOAT *pDeterminant,
CONST D3DXMATRIX *pM)
{
int a, i, j;
D3DXMATRIX out;
D3DXVECTOR4 v, vec[3];
FLOAT det;
det = D3DXMatrixDeterminant(pM);
if(!det )
return NULL;
if(pDeterminant)
*pDeterminant = det;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(j != i)
{
a = j;
if(j > i)
a = a-1;
vec[a].x = pM->m[j][0];
vec[a].y = pM->m[j][1];
vec[a].z = pM->m[j][2];
vec[a].w = pM->m[j][3];
}
}
D3DXVec4Cross(&v, &vec[0], &vec[1], &vec[2]);
// pow(-1.0f, i) = (-1.0f) hoch i
out.m[0][i] = pow(-1.0f, i) * v.x / det;
out.m[1][i] = pow(-1.0f, i) * v.y / det;
out.m[2][i] = pow(-1.0f, i) * v.z / det;
out.m[3][i] = pow(-1.0f, i) * v.w / det;
}
*pOut = out;
return pOut;
}
FLOAT *pDeterminant,
CONST D3DXMATRIX *pM)
{
int a, i, j;
D3DXMATRIX out;
D3DXVECTOR4 v, vec[3];
FLOAT det;
det = D3DXMatrixDeterminant(pM);
if(!det )
return NULL;
if(pDeterminant)
*pDeterminant = det;
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
{
if(j != i)
{
a = j;
if(j > i)
a = a-1;
vec[a].x = pM->m[j][0];
vec[a].y = pM->m[j][1];
vec[a].z = pM->m[j][2];
vec[a].w = pM->m[j][3];
}
}
D3DXVec4Cross(&v, &vec[0], &vec[1], &vec[2]);
// pow(-1.0f, i) = (-1.0f) hoch i
out.m[0][i] = pow(-1.0f, i) * v.x / det;
out.m[1][i] = pow(-1.0f, i) * v.y / det;
out.m[2][i] = pow(-1.0f, i) * v.z / det;
out.m[3][i] = pow(-1.0f, i) * v.w / det;
}
*pOut = out;
return pOut;
}
Weitere wichtige Funktionen zur Berechnung einer inversen Matrix
Determinate einer Matrix
INLINE FLOAT D3DXMatrixDeterminant(CONST D3DXMATRIX *pM)
{
D3DXVECTOR4 minor, v1, v2, v3;
FLOAT det;
v1.x = pM->m[0][0];
v1.y = pM->m[1][0];
v1.z = pM->m[2][0];
v1.w = pM->m[3][0];
v2.x = pM->m[0][1];
v2.y = pM->m[1][1];
v2.z = pM->m[2][1];
v2.w = pM->m[3][1];
v3.x = pM->m[0][2];
v3.y = pM->m[1][2];
v3.z = pM->m[2][2];
v3.w = pM->m[3][2];
D3DXVec4Cross(&minor,&v1,&v2,&v3);
det = -(pM->m[0][3] * minor.x +
pM->m[1][3] * minor.y +
pM->m[2][3] * minor.z +
pM->m[3][3] * minor.w);
return det;
}
{
D3DXVECTOR4 minor, v1, v2, v3;
FLOAT det;
v1.x = pM->m[0][0];
v1.y = pM->m[1][0];
v1.z = pM->m[2][0];
v1.w = pM->m[3][0];
v2.x = pM->m[0][1];
v2.y = pM->m[1][1];
v2.z = pM->m[2][1];
v2.w = pM->m[3][1];
v3.x = pM->m[0][2];
v3.y = pM->m[1][2];
v3.z = pM->m[2][2];
v3.w = pM->m[3][2];
D3DXVec4Cross(&minor,&v1,&v2,&v3);
det = -(pM->m[0][3] * minor.x +
pM->m[1][3] * minor.y +
pM->m[2][3] * minor.z +
pM->m[3][3] * minor.w);
return det;
}
Kreuzprodukt dreier vierdimensionaler Vektoren
CONST D3DXVECTOR4 *pV1,
CONST D3DXVECTOR4 *pV2,
CONST D3DXVECTOR4 *pV3)
{
pOut->x = pV1->y * (pV2->z * pV3->w - pV3->z * pV2->w) -
pV1->z * (pV2->y * pV3->w - pV3->y * pV2->w) +
pV1->w * (pV2->y * pV3->z - pV2->z *pV3->y);
pOut->y = -(pV1->x * (pV2->z * pV3->w - pV3->z * pV2->w) -
pV1->z * (pV2->x * pV3->w - pV3->x * pV2->w) +
pV1->w * (pV2->x * pV3->z - pV3->x * pV2->z));
pOut->z = pV1->x * (pV2->y * pV3->w - pV3->y * pV2->w) -
pV1->y * (pV2->x *pV3->w - pV3->x * pV2->w) +
pV1->w * (pV2->x * pV3->y - pV3->x * pV2->y);
pOut->w = -(pV1->x * (pV2->y * pV3->z - pV3->y * pV2->z) -
pV1->y * (pV2->x * pV3->z - pV3->x * pV2->z) +
pV1->z * (pV2->x * pV3->y - pV3->x * pV2->y));
return pOut;
}