Loading [MathJax]/jax/output/HTML-CSS/jax.js

2011-07-08

Macierz odwrotna

Macierz A nazywamy macierzą odwrotną do B jeśli:

AB=BA=I
Gdzie I to macierz jednostkowa. A i B to macierze kwadratowe. Macierz odwrotną do macierzy A oznaczamy jako A1.

Własności macierzy odwrotnej

(A1)1=A
(AT)1=(A1)T
(kA)1=1kA1
(AB)1=B1A1
(A1A2...AN)1=A1N...A12A11
detA1=1detA

Wyznaczanie macierzy odwrotnej

A1=1detA(CT)ij=1detA(Cji)=1detA[C11C21Cn1C12C22Cn2C1nC2nCnn]

Macierz Cji to transponowana macierz dopełnień algebraicznych macierzy A.

Zauważmy, że jeśli detA=0 macierz odwrotna do A nie istnieje.

Zastosowanie w grafice 3D

Wymnażając punkt P przez macierz M otrzymujemy nowy punkt P. Mnożąc punkt P przez macierz M1 otrzymujemy spowrotem punkt P. Punkt P może być tutaj równie dobrze macierzą. Macierz M to z reguły transformacja układu współrzędnych np: świat-kamera, lokalny układ obiektu-świat albo dowolny inny. Macierz M jest najczęściej złożeniem macierzy rotacji, transpozycji, skalowania.

Przykład wyznaczenia macierzy odwrotnej 3x3 w C#:

public Matrix3 Inverted
{
    get
    {
        double det = Determinant;

        Debug.Assert(det != 0);

        return new Matrix3(

            (M22 * M33 - M23 * M32) / det, 
            -(M12 * M33 - M13 * M32) / det, 
            (M12 * M23 - M13 * M22) / det, 

            -(M21 * M33 - M23 * M31) / det, 
            (M11 * M33 - M13 * M31) / det, 
            -(M11 * M23 - M13 * M21) / det, 

            (M21 * M32 - M22 * M31) / det, 
            -(M11 * M32 - M12 * M31) / det, 
            (M11 * M22 - M12 * M21) / det
        );
    }
}

Przykład szybkiego wyznaczenia macierzy odwrotnej 4x4 w C#:

public Matrix4 Inverted
{
    get
    {
        var d01 = M31 * M42 - M41 * M32;
        var d02 = M31 * M43 - M41 * M33;
        var d12 = M32 * M43 - M42 * M33;
        var d13 = M32 * M44 - M42 * M34;
        var d23 = M33 * M44 - M43 * M34;
        var d30 = M34 * M41 - M44 * M31;

        double r_11 = M22 * d23 - M23 * d13 + M24 * d12;
        double r_21 = -(M21 * d23 + M23 * d30 + M24 * d02);
        double r_31 = M21 * d13 + M22 * d30 + M24 * d01;
        double r_41 = -(M21 * d12 - M22 * d02 + M23 * d01);

        var s = 1 / (M11 * r_11 + M12 * r_21 + M13 * r_31 + M14 * r_41);

        double r_12 = -(M12 * d23 - M13 * d13 + M14 * d12) * s;
        double r_22 = (M11 * d23 + M13 * d30 + M14 * d02) * s;
        double r_32 = -(M11 * d13 + M12 * d30 + M14 * d01) * s;
        double r_42 = (M11 * d12 - M12 * d02 + M13 * d01) * s;

        d01 = M11 * M22 - M21 * M12;
        d02 = M11 * M23 - M21 * M13;
        d12 = M12 * M23 - M22 * M13;
        d13 = M12 * M24 - M22 * M14;
        d23 = M13 * M24 - M23 * M14;
        d30 = M14 * M21 - M24 * M11;

        return new Matrix4(
            r_11 * s, 
            r_12, 
            (M42 * d23 - M43 * d13 + M44 * d12) * s, 
            -(M32 * d23 - M33 * d13 + M34 * d12) * s,

            r_21 * s, 
            r_22, 
            -(M41 * d23 + M43 * d30 + M44 * d02) * s, 
            (M31 * d23 + M33 * d30 + M34 * d02) * s,

            r_31 * s, 
            r_32, 
            (M41 * d13 + M42 * d30 + M44 * d01) * s, 
            -(M31 * d13 + M32 * d30 + M34 * d01) * s,

            r_41 * s, 
            r_42, 
            -(M41 * d12 - M42 * d02 + M43 * d01) * s, 
            (M31 * d12 - M32 * d02 + M33 * d01) * s
        );
    }
}

Brak komentarzy:

Prześlij komentarz