Wie erstelle ich eine Rotationsmatrix mit lesbaren Winkeln von Grund auf?

Das einzige, was mich immer daran gehindert hat, 3D-Programmierung zu machen, ist, nicht zu verstehen, wie Mathematik funktioniert. Ich kann gut mit Mathematik umgehen, indem ich den Ablauf mit Methoden und Funktionen programmiere, dann ist alles klar und logisch für mich, aber in mathematischer Notation kann ich daraus einfach keinen Kopf oder Zahl machen.

Ich habe Webseiten gelesen und Videos von Instituten angeschaut, die versucht haben, dies zu erklären, aber alle verwenden mathematische Notation und ich verliere mich einfach darin, mein Verstand wird es nicht in etwas Verständliches übersetzen. Ich könnte dort einen Defekt haben.

Auch, es interessiert mich nicht, irgendjemanden Code zu benutzen, ich möchte die Mechanik dahinter verstehen, die Logik. Ich würde gerne den Code eines anderen verwenden, aber ich möchte wirklich verstehen, wie es funktioniert.

Die Frag

annst du es mir in einfachen Worten erkläreohn mathematische Notation, nur Notation / Funktionen / Pseudocode programmieren, wie man eine Matrixtransformation entlang aller 3 Achsen implementiert?

Ideally, was ich will, ist das Material / Verständnis, um eine Methode / ein Objekt zu schreiben, bei dem ich die Winkel von 3 Achsen definieren kann, ähnlich wie bei glRotate, um die Sammlung von Quads / Dreiecken zu drehen, die ich habe. (Ich versuche, eine 3D-Rotation von Würfelformen zu programmieren, ohne auf OpenGL-Funktionen zugreifen zu können, da dies bei jeder Änderung in der Anzeigeliste in einem Zeichnungsaufruf erfolgt.)

Was habe ich gemacht

Ich habe versucht, eine 90-Grad-Transformationsfunktion zu erstellen, um den Dreh- und Angelpunkt der Mathematik zu finden, aber es gelang mir nicht, eine geeignete Matrix zu erstellen, die theoretisch am einfachsten zu erstellen gewesen wäre. Sie können meinen gescheiterten Versuch in seiner ganzen Pracht auf @ sehhttp: //jsfiddle.net/bLfg0tj8/5

Vec3 = function(x,y,z) {
    this.x = x;
    this.y = y;
    this.z = z;
}
Matrix = function Matrix() {
    this.matrixPoints = new Array();    
    this.rotationPoint = new Vec3(0,0,0);
    this.rotationAngle = 90;
}
Matrix.prototype.addVector = function(vector) {
    this.matrixPoints.push(vector);
}
Matrix.prototype.setRotationPoint = function(vector) {
    this.rotationPoint = vector; 
}
Matrix.prototype.setRotationAngle = function(angle) {
    this.rotationAngle = angle;
}
Matrix.prototype.populate = function() {
    translateToOrigin =     [[1,0,0-this.rotationPoint.x],
                                  [0,1,0-this.rotationPoint.y],
                                  [0,0,0-this.rotationPoint.z]];
    rotationMatrix =         [[0,-1,0],
                                  [0,1,0],
                                  [0,0,1]];
    translateEnd =         [[1,0,this.rotationPoint.x],
                                  [0,1,this.rotationPoint.y],
                                  [0,0,this.rotationPoint.z]];
    currentColumn = 0;
    currentRow = 0;
    this.combomatrix = this.mergeMatrices(this.mergeMatrices(translateEnd,rotationMatrix),
                                          translateToOrigin);
}
Matrix.prototype.transform = function() {
    newmatrix = new Array();
    for(c = 0;c<this.matrixPoints.length;c++) {
        newmatrix.push(this.applyToVertex(this.matrixPoints[c]));
    }
    return newmatrix;
}
Matrix.prototype.applyToVertex = function(vertex) {
    ret = new Vec3(vertex.x,vertex.y,vertex.z);
    ret.x = ret.x + this.combomatrix[0][0] * vertex.x +
            this.combomatrix[0][1] * vertex.y +
            this.combomatrix[0][2] * vertex.z;
    
    ret.y = ret.y + this.combomatrix[1][0] * vertex.x +
            this.combomatrix[1][1] * vertex.y +
            this.combomatrix[1][2] * vertex.z;
    
    ret.z = ret.z + this.combomatrix[2][0] * vertex.x +
            this.combomatrix[2][1] * vertex.y +
            this.combomatrix[2][2] * vertex.z;
    return ret;
}
Matrix.prototype.mergeMatrices = function(lastStep, oneInFront) {
    step1 = [[0,0,0],[0,0,0],[0,0,0]];
    step1[0][0] =   lastStep[0][0] * oneInFront[0][0] + 
                    lastStep[0][1] * oneInFront[1][0] + 
                    lastStep[0][2] * oneInFront[2][0];
    
    step1[0][1] =   lastStep[0][0] * oneInFront[0][1] + 
                    lastStep[0][1] * oneInFront[1][1] + 
                    lastStep[0][2] * oneInFront[2][1];
    
    step1[0][2] =   lastStep[0][0] * oneInFront[0][2] + 
                    lastStep[0][1] * oneInFront[1][2] + 
                    lastStep[0][2] * oneInFront[2][2];
    //============================================================
    step1[1][0] =   lastStep[1][0] * oneInFront[0][0] + 
                    lastStep[1][1] * oneInFront[1][0] + 
                    lastStep[1][2] * oneInFront[2][0];
    
    step1[1][1] =   lastStep[1][0] * oneInFront[0][1] + 
                    lastStep[1][1] * oneInFront[1][1] + 
                    lastStep[1][2] * oneInFront[2][1];
    
    step1[1][2] =   lastStep[1][0] * oneInFront[0][2] + 
                    lastStep[1][1] * oneInFront[1][2] + 
                    lastStep[1][2] * oneInFront[2][2];
    //============================================================
    step1[2][0] =   lastStep[2][0] * oneInFront[0][0] + 
                    lastStep[2][1] * oneInFront[1][0] + 
                    lastStep[2][2] * oneInFront[2][0];
    
    step1[2][1] =   lastStep[2][0] * oneInFront[0][1] + 
                    lastStep[2][1] * oneInFront[1][1] + 
                    lastStep[2][2] * oneInFront[2][1];
    
    step1[2][2] =   lastStep[2][0] * oneInFront[0][2] + 
                    lastStep[2][1] * oneInFront[1][2] + 
                    lastStep[2][2] * oneInFront[2][2];
    return step1;
}
Matrix.prototype.getCurrentMatrix = function() {
    return this.matrixPoints;
}
myvectors = [new Vec3(50,50,0), new Vec3(20,80,0), new Vec3(80, 80, 0)];

function drawVectors(vectors,color) {
    for(c=0;c<vectors.length;c++) {
        document.getElementById("whoa").innerHTML += '<div style="color:'+color+';position:absolute;left:'+vectors[c].x+'px; top:'+vectors[c].y+'px;z-index:'+vectors[c].z+';">('+c+').</div>';
    }
}
matrix = new Matrix();
for(c=0;c<myvectors.length;c++) {
    matrix.addVector(myvectors[c]);
}
matrix.setRotationPoint(new Vec3(50,70,0));
matrix.populate();
somematrix = matrix.transform();
drawVectors(matrix.getCurrentMatrix(),"lime"); // draw current matrix that was hand coded
drawVectors([matrix.rotationPoint],'white'); // draw rotation point
drawVectors(somematrix,"red"); // transformed matrix... somehow two points merge
<div id="whoa" style="position:relative;top:50px;left:150px;background-color:green;color:red;width:400px;height:300px;">
    &nbsp;
</div>

Der grüne Text ist das ursprüngliche Dreieck, der weiße Punkt der Mittelpunkt, der rote Punkt die fehlgeschlagene Transformation (ich denke, weil er nicht um den Mittelpunkt herum ausgerichtet ist). Das Tutorial, in dem ich war, dachte mir, wie man Matrizen zu einer kombinierten Matrix kombiniert, aber ich glaube, ich habe es irgendwo vermasselt.

ie gesagt, es ist wirklich sehr, sehr schwer für mich, die mathematische Notation zu verstehen und zu sprechen. Und nicht hilfreich ist, dass die meisten Lehrer Teile der Erklärung überspringen. Ich habe 2 Stunden alleine gebraucht, um zu verstehen, wann Matrizen multipliziert werden müssen, um jeden Schritt zu addieren, anstatt einfach weiter zu multiplizieren. Yay für Erklärungen.

Ein praktisches Beispiel womit ich arbeite / arbeiten möchte

Zum Beispiel habe ich einen Würfel, der aus einer Wavefront-Obj-Datei geladen wurde, die sich in der Welt unter @ befinde

x = 50
y = 100
z = 200

Der Würfel wird mit Quads und einigen UV-Karten gezeichnet. Keine Probleme hier. Es wird wunderschön wiedergegeben, wobei alle Texturen korrekt angezeigt werden.

Dies sind die Ortskoordinaten für jede "Fläche" des Würfels, die mit einem Quad gezeichnet wird.

// Front face
-1.0, -1.0,  1.0,
 1.0, -1.0,  1.0,
 1.0,  1.0,  1.0,
-1.0,  1.0,  1.0,

// Back face
-1.0, -1.0, -1.0,
-1.0,  1.0, -1.0,
 1.0,  1.0, -1.0,
 1.0, -1.0, -1.0,

// Top face
-1.0,  1.0, -1.0,
-1.0,  1.0,  1.0,
 1.0,  1.0,  1.0,
 1.0,  1.0, -1.0,

// Bottom face
-1.0, -1.0, -1.0,
 1.0, -1.0, -1.0,
 1.0, -1.0,  1.0,
-1.0, -1.0,  1.0,

// Right face
 1.0, -1.0, -1.0,
 1.0,  1.0, -1.0,
 1.0,  1.0,  1.0,
 1.0, -1.0,  1.0,

// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0,  1.0,
-1.0,  1.0,  1.0,
-1.0,  1.0, -1.0

So funktioniert das alles super. Aber was ist, wenn ich möchte, dass dieser Würfel um 90 Grad entlang der x-Achse und um 45 Grad um die z-Achse gedreht wird? Ich kann glRotate nicht verwenden, da ich im Moment, in dem ich die Daten an das tesselator-Objekt übergebe, keine Matrixtransformationen über die opengl-Funktionen ausführen kann, da die Daten nur aufgenommen und nicht tatsächlich per se gerendert werden.

Die Art und Weise, wie die Daten gespeichert werden, ist wie folgt:

WaveFrontObject()
   |
   |-> Groups(String groupname)
        |
        |-> Faces()
              |
              |-> Vertex(float x, float y, float z)[] 
              |-> Float UVmap[] corresponding to each vertex
              |-> drawFace() // Draws the face as a quad or triangle

Also wird jede der oben angegebenen Koordinaten als Fläche des Wellenfrontobjekts in der Gruppe "Würfel" gespeichert.

Wenn der Würfel zum Tesselator hinzugefügt wird, wird er in die richtigen Koordinaten der Welt übersetzt und normal wiedergegeben.

Es wird jedoch immer das gleiche gerendert. Wenn ich möchte, dass es in einem Winkel gerendert wird, müsste ich in diesem Moment ein separates Wellenfrontobjekt erstellen, um dies tun zu können. Nach meiner Meinung ist das Wahnsinn, wenn man es mit etwas Mathe lösen kann.

Needed in der Antwort

Erläuterung Schritt für Schritt, wie man eine Übersetzungsmatrix erstellt, und ein Versuch, mir die Mathematik zu erklären.

Erläuterung, wie die Übersetzungsmatrix auf die Quads / Dreiecke in den Gesichtern angewendet wird, während sie sich an der Mitte ihrer Position orientieren.

x = 50,5 y = 100,5 z = 200,5

Einiges Beispiel / Pseudocode für die Erklärung.

Die verwendete Programmiersprache ist nicht wirklich relevant, solange sie zur C-Familie gehört.

Bitte versuchen Sie, sich von der mathematischen Notation fernzuhalten / zu sprechen. Ich weiß nicht, was Alpha-Beta ist. Ich weiß, was X-Achse, Y-Achse und Z-Achse sind. Ich weiß, was Winkel sind, aber ich weiß nicht, welche Namen Mathematiker dafür finden.

Wenn Sie mathematische Namen verwenden möchten, erklären Sie mir bitte, was diese in der 3D-Welt / im 3D-Code sind und wie sie gebildet / berechnet werden.

Ich möchte einfach eine Methode / ein Objekt nach dem Vorbild von @ erstelle

Matrix.transformVertices(vertices[], 90deg x, 45 deg y, 0 deg z);

Antworten auf die Frage(2)

Ihre Antwort auf die Frage