Affine Transformationen mit Matrix-Mathematik verstehen

Inspiriert von Prof. Wildberger in seiner Vorlesungsreihe über lineare Algebra, möchte ich seine mathematischen Ideen mit Flash umsetzen. Wir werden nicht in die mathematische Manipulation von Matrizen durch lineare Algebra eintauchen: nur durch Vektoren. Dieses Verständnis, obwohl es die Eleganz der linearen Algebra abschwächt, reicht aus, um uns einige interessante Möglichkeiten der 2x2-Matrix-Manipulation vorzustellen. Insbesondere verwenden wir es, um zur Laufzeit verschiedene Scherungs-, Neigungs-, Spiegelungs- und Skalierungseffekte auf Bilder anzuwenden.


Endergebnisvorschau

Werfen wir einen Blick auf das Endergebnis, auf das wir hinarbeiten werden. Drücken Sie die vier Richtungstasten (nach oben, unten, links, rechts), um einige Effekte zu sehen, die wir mit affinen Transformationen erzielen können.

Wenn Sie nur die linke und rechte Pfeiltaste verwenden, scheint der Fisch in einem pseudo-isometrischen 3D-Raum zu schwimmen.


Schritt 1: Unterschiedliche Koordinatenräume

Grafiken werden in Koordinatenräume gezeichnet. Um sie zu manipulieren, insbesondere um Grafiken zu übersetzen, zu drehen, zu skalieren, zu reflektieren und zu verzerren, ist es wichtig, dass wir Koordinatenräume verstehen. Im Allgemeinen verwenden wir nicht nur einen, sondern mehrere Koordinatenräume in einem einzigen Projekt. Dies gilt nicht nur für Designer, die die Flash-IDE verwenden, sondern auch für Programmierer, die ActionScript schreiben.

In Flash IDE geschieht dies immer dann, wenn Sie Ihre Zeichnungen in MovieClip-Symbole konvertieren: Jedes Symbol hat seinen eigenen Ursprung.

Das Bild oben zeigt den Ursprung des Koordinatenraums der Bühne (roter Punkt) und den des Koordinatenraums des Symbols (durch Fadenkreuz markierter Registrierungspunkt). Um zu erfahren, in welchem ​​Bereich Sie sich gerade befinden, können Sie den Balken unterhalb der Zeitleiste der Flash IDE beobachten, wie in der folgenden Abbildung dargestellt.

(Ich verwende Flash CS3, daher kann sich der Speicherort für CS4 und CS5 unterscheiden.) Ich möchte betonen, dass es unterschiedliche Koordinatenräume gibt und dass Sie mit ihnen bereits vertraut sind.


Schritt 2: Die Begründung

Nun gibt es einen guten Grund dafür. Wir können einen Koordinatenraum als Referenz verwenden, um den anderen Koordinatenraum zu ändern. Das mag sich alien anhören, deshalb habe ich die Flash-Präsentation unten eingefügt, um meine Erklärung zu erleichtern. Klicken Sie auf die roten Pfeile und ziehen Sie sie. Spielen Sie damit herum.

Im Hintergrund ist ein blaues Gitter und im Vordergrund ein rotes Gitter. Die blauen und roten Pfeile sind anfangs entlang der x- und y-Achse des Flash-Koordinatenraums ausgerichtet, deren Mitte ich zur Bühnenmitte verschoben habe. Das blaue Gitter ist ein Referenzgitter. Die Rasterlinien ändern sich nicht, wenn Sie mit den roten Pfeilen interagieren. Das rote Gitter hingegen kann durch Ziehen der roten Pfeile neu ausgerichtet und skaliert werden.

Beachten Sie, dass die Pfeile auch eine wichtige Eigenschaft dieser Gitter anzeigen. Sie geben den Begriff einer Einheit von x und einer Einheit von y in ihrem jeweiligen Raster an. Es gibt zwei rote Pfeile auf dem roten Gitter. Jeder von ihnen gibt die Länge einer Einheit auf der x-Achse und der y-Achse an. Sie bestimmen auch die Orientierung des Koordinatenraums. Nehmen wir den roten Pfeil entlang der x-Achse und verlängern Sie ihn doppelt so lang wie der ursprüngliche Pfeil (blau dargestellt). Beachten Sie die folgenden Bilder.

Wir sehen, dass das auf dem roten Gitter gezeichnete Bild (das grüne Kästchen) jetzt horizontal gestreckt wird, da dieses rote Gitter jetzt doppelt so breit ist. Der Punkt, den ich versuchen möchte, ist ziemlich einfach: Sie können einen Koordinatenraum als Basis verwenden, um einen anderen Koordinatenraum zu ändern.


Schritt 3: Affiner Koordinatenraum

Was ist also ein "affiner Koordinatenraum"? Ich bin sicher, Sie sind vorsichtig genug, um zu beobachten, dass diese Koordinatenräume mit parallelen Gitternetzlinien gezeichnet werden. Nehmen wir zum Beispiel den roten affinen Raum: Es gibt keine Garantie, dass sowohl die x-Achse als auch die y-Achse immer senkrecht zueinander sind, aber seien Sie versichert, dass Sie, egal wie Sie versuchen, die Pfeile zu verändern, zu einem solchen Fall kommen werden wie nachstehend.


Dieser Koordinatenraum ist nicht ein affiner Koordinatenraum.

Tatsächlich beziehen sich X- und Y-Achsen normalerweise auf den kartesischen Koordinatenraum, wie unten gezeigt.

Beachten Sie, dass die horizontalen und vertikalen Raster senkrecht zueinander stehen. Kartesisch ist eine Art des affinen Koordinatenraums, aber wir können ihn nach Belieben in andere affine Räume umwandeln. Die horizontalen und vertikalen Gitter müssen nicht unbedingt senkrecht zueinander sein.


Beispiel eines affinen Koordinatenraums
Ein weiteres Beispiel für einen affinen Koordinatenraum

Schritt 4: Affine Transformationen

Wie Sie vielleicht schon vermutet haben, sind die affinen Transformationen Translation, Skalierung, Reflektion, Skewing und Rotation.


Ursprünglicher affiner Raum
Skalierter affiner Raum
Affinierter Raum reflektiert
Verdrehter affiner Raum
Gedrehter und skalierter affiner Raum

Unnötig zu sagen, physikalische Eigenschaften wie x, y, scaleX, scaleY und Drehung hängt vom Raum ab. Wenn wir diese Eigenschaften aufrufen, transformieren wir tatsächlich affine Koordinaten.


Schritt 5: Matrix verstehen

Ich hoffe, dass die oben gezeigten Bilder eindeutig genug sind, um die Idee nach Hause zu bringen. Dies liegt daran, dass für Programmierer, die mit FlashDevelop arbeiten, keine Raster angezeigt werden, die von der Flash IDE für Designer angezeigt werden. Alle diese müssen in deinem Kopf leben.

Abgesehen von der Vorstellung dieser Gitter müssen wir auch die Hilfe von einholen Matrix Klasse. Daher ist es wichtig, ein mathematisches Verständnis von Matrizen zu haben. Wir werden daher die Operationen der Matrix hier überarbeiten: Addition und Multiplikation.


Schritt 6: Geometrische Bedeutung der Matrixaddition

Matrixoperationen haben geometrische Bedeutungen. Mit anderen Worten, Sie können sich vorstellen, was sie in einem Diagramm bedeuten. Nehmen wir an, wir haben vier Punkte in unserem Koordinatenraum und möchten sie an einen neuen Ort verschieben. Dies kann mittels Matrixaddition erfolgen. Schauen Sie sich das Bild unten an.

Wie Sie sehen, verschieben wir tatsächlich den gesamten lokalen Koordinatenraum (rote Gitter), in den diese vier Punkte gezeichnet werden. Die Notation zum Ausführen dieser Vorgänge lautet wie folgt:

Wir können auch sehen, dass diese Verschiebung tatsächlich mit einem Vektor von (tx, ty) dargestellt werden kann. Lassen Sie uns Vektoren und statische Punkte in Koordinatenräumen durch Verwendung von Klammern und eckigen Klammern unterscheiden. Ich habe sie im Bild unten umgeschrieben.


Schritt 7: ActionScript-Implementierung

Hier ist eine einfache Implementierung der Matrixaddition. Schauen Sie sich die Kommentare an:

 public class Addition erweitert Sprite public function Addition () var m: Matrix = neue Matrix (); // Instanziierte Matrix m.tx = stage.stageWidth * 0.5; // Verschiebung in xm.ty = stage.stageHeight * 0.5; // Shift in y var d: DottedBox = new DottedBox (); // Benutzerdefinierte Grafik erstellen (gepunktetes Kästchen ist ein Sprite) addChild (d); d.transform.matrix = m; // wende die Matrix auf unsere Grafik an

Schritt 8: Geometrische Bedeutung der Matrixmultiplikation

Die Matrixmultiplikation ist etwas komplizierter als die Matrixaddition, aber Prof. Wildberger hat sie elegant auf diese einfache Interpretation heruntergebrochen. Ich werde demütig versuchen, seine Erklärung zu wiederholen. Für diejenigen, die tiefer in das Verständnis der linearen Algebra eintauchen möchten, lesen Sie die Vorlesungsreihe des Professors.

Beginnen wir mit dem Fall der Identitätsmatrix I.

Aus dem obigen Bild wissen wir, dass die Multiplikation einer beliebigen Matrix A mit der Identitätsmatrix I immer A ergibt. Hier eine Analogie: 6 x 1 = 6; Die Identitätsmatrix wird in dieser Multiplikation mit der Zahl 1 verglichen.

Alternativ können wir das Ergebnis in das folgende Vektorformat schreiben, was unsere Interpretation erheblich vereinfacht:

Die geometrische Interpretation dieser Formel ist in der folgenden Abbildung dargestellt.

Aus dem kartesischen Gitter (linkes Gitter) ist der blaue Punkt bei (2, 1) zu sehen. Wenn wir nun dieses ursprüngliche Gitter von x und y in ein neues Gitter (rechtes Gitter) entsprechend einer Menge von Vektoren (unter dem rechten Gitter) umwandeln, wird der blaue Punkt auf dem neuen Gitter nach (2, 1) verschoben - Wenn wir dies jedoch wieder dem ursprünglichen Raster zuordnen, ist dies derselbe Punkt wie zuvor.

Da wir das ursprüngliche Gitter in ein anderes Gitter transformieren, das die gleichen Vektoren für x und y verwendet, sehen wir keinen Unterschied. In der Tat sind die Änderungen von x und y bei dieser Transformation gleich Null. Das hat es mit gemeint Identitätsmatrix, aus geometrischer Sicht.

Wenn wir jedoch versuchen, ein Mapping mit anderen Transformationen durchzuführen, werden wir einige Unterschiede feststellen. Ich weiß, dass dies nicht das aufschlussreichste Beispiel war, also beginnen wir mit einem anderen Beispiel.


Schritt 9: Skalieren entlang X

Das Bild oben zeigt eine Skalierung des Koordinatenraums. Überprüfen Sie den Vektor von x im transformierten Koordinatenraum: Eine Einheit des transformierten x berücksichtigt zwei Einheiten des ursprünglichen x. Im transformierten Koordinatenraum ist die Koordinate des blauen Punkts immer noch (2, 1). Wenn Sie jedoch versuchen, diese Koordinate aus dem transformierten Gitter auf das ursprüngliche Gitter abzubilden, ist dies (4, 1).

Diese ganze Idee wird durch das Bild oben erfasst. Wie wäre es mit der Formel? Das Ergebnis sollte konsistent sein. lass es uns überprüfen.

Ich bin sicher, Sie erinnern sich an diese Formeln. Nun habe ich ihre jeweiligen Bedeutungen hinzugefügt.

Um jetzt das numerische Ergebnis unseres Beispiels zu überprüfen.

  • Ursprüngliche Koordinate: (2, 1)
  • Vektor auf transformierter x-Achse: (2, 0)
  • Vektor auf transformierter Y-Achse: (0, 1)
  • Erwartetes Ergebnis: (2 * 2 + 0 * 1, 0 * 2 + 1 * 1) = (4, 1)

Sie stimmen miteinander überein! Jetzt können wir diese Idee gerne auf andere Transformationen anwenden. Vorher jedoch eine ActionScript-Implementierung.


Schritt 10: ActionScript-Implementierung

Sehen Sie sich die ActionScript-Implementierung (und die resultierende SWF-Datei) unten an. Beachten Sie, dass eines der überlappenden Kästchen um eine Skala von 2 entlang x gestreckt wird. Ich habe die wichtigen Werte hervorgehoben. Diese Werte werden in den späteren Schritten angepasst, um verschiedene Transformationen darzustellen.

 public class Multiplication erweitert Sprite public function Multiplication () var ref: DottedBox = new DottedBox (); // Referenzgrafik erstellen addChild (ref); ref.x = stage.stageWidth * 0,5; ref.y = stage.stageHeight * 0,5; var m: Matrix = neue Matrix (); // Instanziierte Matrix m.tx = stage.stageWidth * 0.5; // Verschiebung in xm.ty = stage.stageHeight * 0.5; // Verschiebung in y m.a = 2; m.c = 0; m.b = 0; md = 1; var d: DottedBox = new DottedBox (); // die benutzerdefinierte Grafik erstellen addChild (d); d.transform.matrix = m // wendet die Matrix auf unsere Grafik an

Schritt 11: Skalieren von X und Y

Hier haben wir das Gitter entlang der X- und Y-Achse um einen Faktor von zwei skaliert. Der blaue Punkt befindet sich vor der Transformation im ursprünglichen Raster (2, 1) und nach der Transformation im ursprünglichen Gitter (4, 2). (Natürlich ist es immer noch bei (2, 1) im Neu Raster nach der Transformation.)

Und um das Ergebnis numerisch zu bestätigen…

… Sie passen wieder zusammen! Um dies in der ActionScript-Implementierung zu sehen, ändern Sie einfach den Wert von m von 1 bis 2.

(Beachten Sie, dass die Streckrichtung von y nach unten und nicht nach oben verläuft, da y in Flash nach unten, jedoch in dem normalen kartesischen Koordinatenraum nach oben, den ich im Diagramm verwendet habe, nach oben geht.)


Schritt 12: Reflexion

Hier haben wir das Gitter entlang der x-Achse mit diesen zwei Vektoren reflektiert, sodass sich die Position des blauen Punkts im ursprünglichen Gitter von (2, 1) in (-2, 1) ändert. Die numerische Berechnung lautet wie folgt:

Die ActionScript-Implementierung ist dieselbe wie zuvor, verwendet jedoch stattdessen diese Werte: m.a = -1, m.b = 0 um den Vektor für die x-Transformation darzustellen, und: m.c = 0 und m. d = 1 um den Vektor für die y-Transformation darzustellen.

Wie wäre es, gleichzeitig über x und y zu reflektieren? Schauen Sie sich das Bild unten an.

Numerisch im Bild unten berechnet.

Für die ActionScript-Implementierung… Nun, ich bin mir sicher, dass Sie die Werte kennen, die in die Matrix eingefügt werden sollen. m.a = -1, m.b = 0 um den Vektor für die x-Transformation darzustellen; m.c = 0 und m. d = -1 um den Vektor für die y-Transformation darzustellen. Ich habe die endgültige SWF-Datei unten aufgeführt.


Schritt 13: Schrägstellen und Scheren

Skewing bringt etwas Spaß mit sich. Im Fall des Bildes unten wurde die X-Achse des transformierten Gitters neu ausgerichtet und skaliert. Vergleichen Sie die roten Pfeile in beiden unteren Rastern: Sie sind unterschiedlich, die y-Achse bleibt jedoch unverändert.


Schiefen

Visuell scheint es, dass eine Verzerrung entlang der y-Richtung auftritt. Dies ist wahr, weil unsere transformierte x-Achse jetzt eine y-Komponente in ihrem Vektor hat.

Numerisch ist das, was passiert…

In Bezug auf die Implementierung habe ich die Tweaks unten aufgeführt.

  • m.a = 2
  • m.b = 1
  • m.c = 0
  • md = 1

Ich bin mir sicher, dass Sie an diesem Punkt die Dinge selbst ausprobieren möchten

  • die Orientierung der transformierten y-Achse unter Beibehaltung der x-Achse
  • die Orientierung beider Achsen insgesamt

Ich habe die Flash-Ausgabe für beide Fälle wie folgt eingefügt. Leser, die mit diesen Werten etwas Hilfe wünschen, können Sie hier nachlesen Multiplication_final.as im Quelldownload.


Schritt 14: Rotation

Ich betrachte Rotation als eine Untermenge des Schräglaufs. Der einzige Unterschied besteht darin, dass bei der Drehung die Größe einer Einheit sowohl der x- als auch der y-Achse beibehalten wird, ebenso wie die Rechtwinkligkeit zwischen den beiden Achsen.

ActionScript bietet tatsächlich eine Methode in der Matrix Klasse, drehen(), um dies zu tun. Aber lass uns das trotzdem durchgehen.

Nun wollen wir die Größe einer Längeneinheit in x und y nicht vom ursprünglichen Gitter abändern. nur um die Orientierung von jedem zu ändern. Wir können die Trigonometrie nutzen, um zu dem im Bild oben gezeigten Ergebnis zu gelangen. Bei einem gegebenen Drehwinkel a erhalten wir das gewünschte Ergebnis, indem wir Vektoren von (cos a, sin a) für die x-Achse und (-sin a, cos a) für die y-Achse verwenden. Die Größe für jede neue Achse ist immer noch eine Einheit, aber jede Achse steht im Vergleich zu den Originalen in einem Winkel von a.

Nehmen Sie für die ActionScript-Implementierung an, dass der Winkel a 45 Grad (d. H. 0,25 * Pi-Radiant) beträgt, und passen Sie die Matrixwerte wie folgt an:

 var a: Zahl = 0,25 * Math.PI m.a = Math.cos (a); m.c = -1 * Math.sin (a); m.b = Math.sin (a); md = Math.cos (a);

Die vollständige Quelle kann in angegeben werden Multiplication_final.as.


Schritt 15: Anwendung

Eine Vektorinterpretation einer 2x2-Matrix eröffnet uns Raum zum Erforschen. Seine Anwendung bei der Bearbeitung von Bitmaps (BitmapData, LineBitmapStyle, LineGradientStyle, etc.) ist weit verbreitet - aber ich denke, ich werde das für ein anderes Tutorial speichern. Für den Fall dieses Artikels werden wir versuchen, unser Sprite zur Laufzeit so zu verzerren, dass es aussieht, als ob es tatsächlich in 3D gedreht wird.


Ansicht einer isometrischen Pseudo-3D-Welt

Aus dem obigen Bild können wir sehen, dass in einer Welt mit einer isometrischen Ansicht jede Grafik, die "stehend" ist, ihren y-Achsen-Vektor unverändert lässt, während sich der x-Achsen-Vektor dreht. Beachten Sie, dass sich eine Längeneinheit für die x- und y-Achse nicht ändert. In anderen Achsen darf also keine Skalierung erfolgen, es muss lediglich um die x-Achse gedreht werden.

Hier ist ein Beispiel für diese Idee in Flash. Klicken Sie auf eine beliebige Stelle auf der Bühne und ziehen Sie herum, um die Neigung des Fisches zu sehen. Loslassen, um die Interaktion zu beenden.

Hier ist das wichtige Stück von Actionscript. Ich habe die entscheidenden Linien hervorgehoben, die die X-Achsendrehung behandeln. Sie können sich auch darauf beziehen FakeIso.as.

 private var f1: Fisch, m: Matrix; private var disp: Punkt; private var AchseX: Punkt, AchseY: Punkt; public function FakeIso () disp = neuer Punkt (stage.stageWidth * 0.5, stage.stageHeight * 0.5); m = neue Matrix (); m.tx = disp.x; m.ty = disp.y; // Verschiebe in die Mitte der Stufe f1 = new Fish (); addChild (f1); f1.transform.matrix = m; // Transformation auf Fischachse anwendenX = neuer Punkt (1, 0); // Vektor für die x - AchsenachseY = neuer Punkt (0, 1); // Vektor für die Y-Achse stage.addEventListener (MouseEvent.MOUSE_DOWN, start); // Interaktion starten stage.addEventListener (MouseEvent.MOUSE_UP, end); // Interaktion beenden private Funktion start (e: MouseEvent): void f1.addEventListener (Event.ENTER_FRAME, Update);  private function end (e: MouseEvent): void f1.removeEventListener (Event.ENTER_FRAME, Aktualisierung);  Aktualisierung privater Funktionen (e: Event): void axisX.setTo (mouseX - f1.x, mouseY - f1.y); // Orientierung bestimmen (aber auch die Größe geändert) axisX.normalize (1); // Stärke des Vektors mit neuer Ausrichtung auf 1 Einheit festlegen apply2Matrix (); // Matrix auf Fische anwenden private Funktion apply2Matrix (): void m.setTo (axisX.x, axisX.y, axisY.x, axisY.y, disp.x, disp.y); f1.transform.matrix = m; 

Hier habe ich die Point-Klasse zum Speichern von Vektoren verwendet.


Schritt 16: Tastatursteuerung hinzufügen

In diesem Schritt werden wir versuchen, Tastatursteuerungen hinzuzufügen. Der Standort des Fisches wird entsprechend seiner Geschwindigkeit aktualisiert, velo. Wir definieren inkrementelle Schritte für die positive (im Uhrzeigersinn) und negative (gegen den Uhrzeigersinn) Drehung.

 velo = neuer Punkt (1, 0); // velo wird verwendet, um die x-Achse zu definierenY = new Point (0, 1); delta_positive = neue Matrix (); delta_positive.rotate (Math.PI * 0,01); // positive Rotation delta_negative = new Matrix (); delta_negative.rotate (Math.PI * -0,01); // negative Drehung

Nach einem Tastendruck, velo wird drehen:

 private function keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.LEFT) velo = delta_negative.transformPoint (velo) // Velo gegen den Uhrzeigersinn drehen else if (e.keyCode == Keyboard.RIGHT ) velo = delta_positive.transformPoint (velo) // Velo im Uhrzeigersinn drehen

Nun werden wir versuchen, für jeden Rahmen die Vorderseite des Fisches zu färben und den Fisch ebenfalls zu verzerren. Wenn die Geschwindigkeit, velo, hat eine Stärke von mehr als 1 und wir wenden es auf die Matrix des Fisches an, m, Wir erhalten auch einen Skalierungseffekt. Um diese Möglichkeit auszuschalten, normalisieren wir die Geschwindigkeit und wenden diese nur auf die Matrix des Fisches an.

 Aktualisierung privater Funktionen (e: Event): void var front_side: Boolean = velo.x> 0 // Überprüfung der Vorderseite von Fischen if (front_side) f1.colorBody (0x002233,0.5) // // Einfärben der Vorderseite of fish else f1.colorBody (0xFFFFFF, 0.5) // Weiß auf Rückseite der Fische aufgetragen disp = disp.add (velo); // aktuelle Verschiebung mit der Geschwindigkeit aktualisieren var velo_norm: Point = velo.clone (); // Wenn velo> 0 ist, müssen wir 1 Längeneinheit für x neu berechnen. velo_norm.normalize (1); // Beachten Sie, dass die X-Achse mehr als 1 eine Skalierung durchführt. Wir wollen das nicht für jetzt m.setTo (velo_norm.x, velo_norm.y, axisY.x, axisY.y, disp.x, disp.y); f1.transform.matrix = m; 

Schritt 17: Ihre Fische

Klicken Sie auf die Bühne und drücken Sie dann die linke und rechte Pfeiltaste, um die Richtung des Fisches zu ändern.


Schritt 18: Eine weitere Tastatursteuerung

Lassen Sie uns, um die Dinge auf den Punkt zu bringen, auch die Steuerung des y-Achsenvektors zu.

 private function keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.LEFT) velo = delta_negative.transformPoint (velo) else if (e.keyCode == Keyboard.RIGHT) velo = delta_positive.transformPoint (velo) if (e.keyCode == Keyboard.UP) axisY = delta_negative.transformPoint (axisY) else if (e.keyCode == Keyboard.DOWN) axisY = delta_positive.transformPoint (axisY)

Um die Vorderseite des Fisches zu bestimmen, müssen wir nun die Y-Achse einbauen. Hier ist der Code dafür:

 var front_side: Boolean = velo.x * axisY.y> 0 if (front_side) f1.colorBody (0x002233,0.5) else f1.colorBody (0xFFFFFF, 0.5)

Schritt 19: Ihr normaler Fisch

Nun, für manche mag das Ergebnis der Steuerung beider Achsen ein wenig verwirrend sein, aber Sie können jetzt Ihren Fisch schrägstellen, ihn übersetzen, reflektieren und sogar drehen! Probieren Sie die Kombinationen von oben + links, oben + rechts, unten + links, unten + rechts aus.

Prüfen Sie auch, ob Sie die "Vorderseite" von Fischen beibehalten können (Fisch wird grau dargestellt). Tipp: Tippen Sie kontinuierlich auf, dann nach links, dann nach unten und dann nach rechts. Sie machen eine Rotation!

Fazit

Ich hoffe, Sie finden Matrixmathematik nach dem Lesen dieses Artikels als wertvolles Gut für Ihre Projekte. Ich hoffe, ein wenig mehr über Anwendungen der 2x2-Matrix in den kleinen Quick Tips zu schreiben, die sich aus diesem Artikel ergeben Matrix3d was für 3D-Manipulationen unerlässlich ist. Danke fürs Lesen, terima kasih.