Transformationsmatrix invertieren

Runtime

Top Contributor
Hallo,
ich will (wiedermal) etwas mit OpenGL/JOGL machen. Nun habe ich eine Klasse Matrix geschrieben, die eine 4x4 Matrix enthält. Alle Funktionen konnte ich irgendwie implementieren / zusammenguttenbergen, aber bei der Inversion kann / will mir weder der Mathematiklehrer noch Google helfen. Weiss jemand die 16 Formeln aus dem Stand heraus :D oder kennt einen Link, in dem alle Formeln beschrieben sind oder zu einem Gratisprogramm mit dem man die Berechnen kann?
Gruss Cyrill
 
G

Guest2

Gast
Moin,

die Formel für die Inverse einer 4x4 Matrix gibt es z.B. hier: Inverse matrix of 2x2 matrix, 3x3 matrix, 4x4 matrix

(Je nach Problem kann es aber auch sein, das Du nicht die vollständige Inverse brauchst, sondern die Inverse der Rotationskomponente schon reichen würde. Die Rotationskomponente liegt in den oberen linken 3x3 Komponenten der Transformationsmatrix. Die Inverse davon ist dann einfach die Transponierte davon. Wenn Du also z.B. so was wie CubeMapping vorhast, gibt das weniger Rechnerei.)

Viele Grüße,
Fancy
 

AlexSpritze

Bekanntes Mitglied
Schau dir mal das Apache Projekt common math an .. da gibt es schon fertige Implementierungen von Matrizen, die natürlich auch die Inversenberechnung enthalten.
 

Runtime

Top Contributor
Java:
public final class Matrix implements Cloneable {

    double[] mx;

    public Matrix() {
        mx = new double[16];
        identity();
    }

    public Matrix(double[] mx) {
        if (mx.length != 16) {
            throw new IllegalArgumentException("mx.length != 16");
        }
        this.mx = mx;
    }

    public double[] getMatrix() {
        return mx;
    }

    public void multiplicate(double[] nm) {
        int x, a, b;
        double[] tm = new double[16];

        for (x = 0; x < 16; x++) {
            a = x % 4;
            b = (x / 4) * 4;

            tm[ x] = nm[ a] * mx[ b]
                    + nm[ a + 4] * mx[ b + 1]
                    + nm[ a + 8] * mx[ b + 2]
                    + nm[ a + 12] * mx[ b + 3];
        }

        for (x = 0; x < 16; x++) {
            mx[ x] = tm[ x];
        }
    }

    public void multiplicate(Matrix matrix) {
        multiplicate(matrix.mx);
    }

    public void rotate(double alpha, Vector3f dir) {
        double[] rm = new double[16];

        if (dir.length() < 0.0001) {
            return;
        }

        dir = dir.mul(1.0 / dir.length());
        double x = dir.x, y = dir.y, z = dir.z;

        double s = Math.sin(Math.toRadians(alpha));
        double c = Math.cos(Math.toRadians(alpha));

        rm[ 0] = x * x * (1 - c) + c;
        rm[ 4] = x * y * (1 - c) - z * s;
        rm[ 8] = x * z * (1 - c) + y * s;
        rm[ 12] = 0;
        rm[ 1] = x * y * (1 - c) + z * s;
        rm[ 5] = y * y * (1 - c) + c;
        rm[ 9] = y * z * (1 - c) - x * s;
        rm[ 13] = 0;
        rm[ 2] = x * z * (1 - c) - y * s;
        rm[ 6] = y * z * (1 - c) + x * s;
        rm[ 10] = z * z * (1 - c) + c;
        rm[ 14] = 0;
        rm[ 3] = 0;
        rm[ 7] = 0;
        rm[ 11] = 0;
        rm[ 15] = 1;

        multiplicate(rm);
    }

    public void rotate_x(double alpha) {
        rotate(alpha, new Vector3f(1, 0, 0));
    }

    public void rotate_y(double alpha) {
        rotate(alpha, new Vector3f(0, 1, 0));
    }

    public void rotate_z(double alpha) {
        rotate(alpha, new Vector3f(0, 0, 1));
    }

    public void rotate(double alpha) {
        rotate_z(alpha);
    }

    public void rotate(double x, double y, double alpha) {
        rotate(alpha, new Vector3f(x, y, 0));
    }

    public void translate(double xt, double yt, double zt) {
        double[] tm = new double[16];

        tm[ 0] = 1;
        tm[ 4] = 0;
        tm[ 8] = 0;
        tm[ 12] = xt;
        tm[ 1] = 0;
        tm[ 5] = 1;
        tm[ 9] = 0;
        tm[ 13] = yt;
        tm[ 2] = 0;
        tm[ 6] = 0;
        tm[ 10] = 1;
        tm[ 14] = zt;
        tm[ 3] = 0;
        tm[ 7] = 0;
        tm[ 11] = 0;
        tm[ 15] = 1;

        multiplicate(tm);
    }

    public void translate(double tx, double ty) {
        translate(tx, ty, 0);
    }

    public void scale(double xs, double ys, double zs) {
        double[] sm = new double[16];

        sm[ 0] = xs;
        sm[ 4] = 0;
        sm[ 8] = 0;
        sm[ 12] = 0;
        sm[ 1] = 0;
        sm[ 5] = ys;
        sm[ 9] = 0;
        sm[ 13] = 0;
        sm[ 2] = 0;
        sm[ 6] = 0;
        sm[ 10] = zs;
        sm[ 14] = 0;
        sm[ 3] = 0;
        sm[ 7] = 0;
        sm[ 11] = 0;
        sm[ 15] = 1;

        multiplicate(sm);
    }

    public void scale(double sx, double sy) {
        scale(sx, sy, 0);
    }

    public Point3d transform(Point3d p) {
        double wx = p.x * mx[ 0] + p.y * mx[ 4] + p.z * mx[ 8] + mx[ 12];
        double wy = p.x * mx[ 1] + p.y * mx[ 5] + p.z * mx[ 9] + mx[ 13];
        double wz = p.x * mx[ 2] + p.y * mx[ 6] + p.z * mx[ 10] + mx[ 14];

        return new Point3d(wx, wy, wz);
    }

    public Vector3f transform(Vector3f v) {
        double x = v.x * mx[ 0] + v.y * mx[ 4] + v.z * mx[ 8];
        double y = v.x * mx[ 1] + v.y * mx[ 5] + v.z * mx[ 9];
        double z = v.x * mx[ 2] + v.y * mx[ 6] + v.z * mx[ 10];

        return new Vector3f(x, y, z);
    }

    public void identity() {
        mx[ 0] = 1;
        mx[ 4] = 0;
        mx[ 8] = 0;
        mx[ 12] = 0;
        mx[ 1] = 0;
        mx[ 5] = 1;
        mx[ 9] = 0;
        mx[ 13] = 0;
        mx[ 2] = 0;
        mx[ 6] = 0;
        mx[ 10] = 1;
        mx[ 14] = 0;
        mx[ 3] = 0;
        mx[ 7] = 0;
        mx[ 11] = 0;
        mx[ 15] = 1;
    }

    public void rows(Vector3f a, Vector3f b, Vector3f c) {
        double[] rm = new double[16];

        rm[ 0] = a.x;
        rm[ 4] = a.y;
        rm[ 8] = a.z;
        rm[ 12] = 0;
        rm[ 1] = b.x;
        rm[ 5] = b.y;
        rm[ 9] = b.z;
        rm[ 13] = 0;
        rm[ 2] = c.x;
        rm[ 6] = c.y;
        rm[ 10] = c.z;
        rm[ 14] = 0;
        rm[ 3] = 0;
        rm[ 7] = 0;
        rm[ 11] = 0;
        rm[ 15] = 1;

        multiplicate(rm);
    }

    public void columns(Vector3f a, Vector3f b, Vector3f c) {
        double[] cm = new double[16];

        cm[ 0] = a.x;
        cm[ 4] = b.x;
        cm[ 8] = c.x;
        cm[ 12] = 0;
        cm[ 1] = a.y;
        cm[ 5] = b.y;
        cm[ 9] = c.y;
        cm[ 13] = 0;
        cm[ 2] = a.z;
        cm[ 6] = b.z;
        cm[ 10] = c.z;
        cm[ 14] = 0;
        cm[ 3] = 0;
        cm[ 7] = 0;
        cm[ 11] = 0;
        cm[ 15] = 1;

        multiplicate(cm);
    }

    public double determinant() {
        return mx[12] * mx[9] * mx[6] * mx[3]
                - mx[8] * mx[13] * mx[6] * mx[3]
                - mx[12] * mx[5] * mx[10] * mx[3]
                + mx[4] * mx[13] * mx[10] * mx[3]
                + mx[8] * mx[5] * mx[14] * mx[3]
                - mx[4] * mx[9] * mx[14] * mx[3]
                - mx[12] * mx[9] * mx[2] * mx[7]
                + mx[8] * mx[13] * mx[2] * mx[7]
                + mx[12] * mx[1] * mx[10] * mx[7]
                - mx[0] * mx[13] * mx[10] * mx[7]
                - mx[8] * mx[1] * mx[14] * mx[7]
                + mx[0] * mx[9] * mx[14] * mx[7]
                + mx[12] * mx[5] * mx[2] * mx[11]
                - mx[4] * mx[13] * mx[2] * mx[11]
                - mx[12] * mx[1] * mx[6] * mx[11]
                + mx[0] * mx[13] * mx[6] * mx[11]
                + mx[4] * mx[1] * mx[14] * mx[11]
                - mx[0] * mx[5] * mx[14] * mx[11]
                - mx[8] * mx[5] * mx[2] * mx[15]
                + mx[4] * mx[9] * mx[2] * mx[15]
                + mx[8] * mx[1] * mx[6] * mx[15]
                - mx[0] * mx[9] * mx[6] * mx[15]
                - mx[4] * mx[1] * mx[10] * mx[15]
                + mx[0] * mx[5] * mx[10] * mx[15];
    }
    
    public void invert() {
        double[] inverse = new double[16];
        generateInverseMatrix(inverse, mx);
        mx = inverse;
    }

    private boolean generateInverseMatrix(double[] i, double[] m) {
        double x = determinant();
        if (x == 0) {
            return false;
        }

        i[0] = (-m[13] * m[10] * m[7] + m[9] * m[14] * m[7] + m[13] * m[6] * m[11]
                - m[5] * m[14] * m[11] - m[9] * m[6] * m[15] + m[5] * m[10] * m[15]) / x;
        i[4] = (m[12] * m[10] * m[7] - m[8] * m[14] * m[7] - m[12] * m[6] * m[11]
                + m[4] * m[14] * m[11] + m[8] * m[6] * m[15] - m[4] * m[10] * m[15]) / x;
        i[8] = (-m[12] * m[9] * m[7] + m[8] * m[13] * m[7] + m[12] * m[5] * m[11]
                - m[4] * m[13] * m[11] - m[8] * m[5] * m[15] + m[4] * m[9] * m[15]) / x;
        i[12] = (m[12] * m[9] * m[6] - m[8] * m[13] * m[6] - m[12] * m[5] * m[10]
                + m[4] * m[13] * m[10] + m[8] * m[5] * m[14] - m[4] * m[9] * m[14]) / x;
        i[1] = (m[13] * m[10] * m[3] - m[9] * m[14] * m[3] - m[13] * m[2] * m[11]
                + m[1] * m[14] * m[11] + m[9] * m[2] * m[15] - m[1] * m[10] * m[15]) / x;
        i[5] = (-m[12] * m[10] * m[3] + m[8] * m[14] * m[3] + m[12] * m[2] * m[11]
                - m[0] * m[14] * m[11] - m[8] * m[2] * m[15] + m[0] * m[10] * m[15]) / x;
        i[9] = (m[12] * m[9] * m[3] - m[8] * m[13] * m[3] - m[12] * m[1] * m[11]
                + m[0] * m[13] * m[11] + m[8] * m[1] * m[15] - m[0] * m[9] * m[15]) / x;
        i[13] = (-m[12] * m[9] * m[2] + m[8] * m[13] * m[2] + m[12] * m[1] * m[10]
                - m[0] * m[13] * m[10] - m[8] * m[1] * m[14] + m[0] * m[9] * m[14]) / x;
        i[2] = (-m[13] * m[6] * m[3] + m[5] * m[14] * m[3] + m[13] * m[2] * m[7]
                - m[1] * m[14] * m[7] - m[5] * m[2] * m[15] + m[1] * m[6] * m[15]) / x;
        i[6] = (m[12] * m[6] * m[3] - m[4] * m[14] * m[3] - m[12] * m[2] * m[7]
                + m[0] * m[14] * m[7] + m[4] * m[2] * m[15] - m[0] * m[6] * m[15]) / x;
        i[10] = (-m[12] * m[5] * m[3] + m[4] * m[13] * m[3] + m[12] * m[1] * m[7]
                - m[0] * m[13] * m[7] - m[4] * m[1] * m[15] + m[0] * m[5] * m[15]) / x;
        i[14] = (m[12] * m[5] * m[2] - m[4] * m[13] * m[2] - m[12] * m[1] * m[6]
                + m[0] * m[13] * m[6] + m[4] * m[1] * m[14] - m[0] * m[5] * m[14]) / x;
        i[3] = (m[9] * m[6] * m[3] - m[5] * m[10] * m[3] - m[9] * m[2] * m[7]
                + m[1] * m[10] * m[7] + m[5] * m[2] * m[11] - m[1] * m[6] * m[11]) / x;
        i[7] = (-m[8] * m[6] * m[3] + m[4] * m[10] * m[3] + m[8] * m[2] * m[7]
                - m[0] * m[10] * m[7] - m[4] * m[2] * m[11] + m[0] * m[6] * m[11]) / x;
        i[11] = (m[8] * m[5] * m[3] - m[4] * m[9] * m[3] - m[8] * m[1] * m[7]
                + m[0] * m[9] * m[7] + m[4] * m[1] * m[11] - m[0] * m[5] * m[11]) / x;
        i[15] = (-m[8] * m[5] * m[2] + m[4] * m[9] * m[2] + m[8] * m[1] * m[6]
                - m[0] * m[9] * m[6] - m[4] * m[1] * m[10] + m[0] * m[5] * m[10]) / x;

        return true;
    }

    @Override
    public Matrix clone() {
        double[] matrix = new double[mx.length];
        System.arraycopy(mx, 0, matrix, 0, mx.length);
        return new Matrix(matrix);
    }
}
Irgendwas ist falsch (ich hoffe nicht getDeterminant oder generateInverseMatrix) sieht irgendjemand den Fehler vllt gleich? Spielt es eine Rolle, wenn ich eine Matrix invertiere, ob sie Column- oder Row-Major ist?
Edit:
KSKB:
Java:
public class MatrixInversionTest {
    
    public static void main(String[] args) {
        Matrix A = new Matrix();
        A.rotate(13, 15, 120);
        A.translate(13, 54, 62);
        A.scale(2, 4, 13);
        Matrix B = A.clone();
        B.invert();
        
        A.multiplicate(B);
        
        double[] mx = A.getMatrix();
        for (int i = 0; i < mx.length; i++) {
            System.out.println(mx[i]);
        }
    }
    
}
 

Marco13

Top Contributor
In Zeile 287 muss es bei der Berechnung von i[2] nicht "m[3] + m[5]" sondern "m[3] * m[5]" heißen.

:joke:

Mal im ernst: Wo hast du das her, und wie soll man dort einen Fehler erkennen?
 

Runtime

Top Contributor
Weil ich nur zum Spass programmiere und ich dann einfach nicht gerne fremdes Zeug benutze, zudem enthält Apache Common Math noch anderes Zeug, das ich nicht brauchen kann.
 

Marco13

Top Contributor
Nochmal nacheinander:

Warum nimmst du nicht Apache Common Math?
Weil ich ... nicht gerne fremdes Zeug benutze

;)

Genauso wie das bisherige "irgendwoher" ist, kannst du ja auch die benötigten Teile aus der Apache-Lib kopieren... solange du sie nicht weitervertreibst, ist das ja egal ... :bahnhof:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Java Achsen invertieren Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben