Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Effects

Affine Transformationen mit Matrixmathematik verstehen

by
Read Time:16 minsLanguages:
This post is part of a series called You Do The Math.
Circular Motion in AS3: Make One Moving Object Orbit Another
The Math and ActionScript of Curves: Drawing Quadratic and Cubic Curves

German (Deutsch) translation by Nikol Angelowa (you can also view the original English article)

Inspiriert von Prof. Wildberger in seiner Vorlesungsreihe zur linearen Algebra beabsichtige ich, seine mathematischen Ideen mit Flash umzusetzen. Wir werden uns nicht mit der mathematischen Manipulation von Matrizen durch lineare Algebra befassen: nur durch Vektoren. Dieses Verständnis, obwohl es die Eleganz der linearen Algebra verwässert, reicht aus, um uns einige interessante Möglichkeiten der 2x2-Matrixmanipulation vorzustellen. Insbesondere werden wir es verwenden, um zur Laufzeit verschiedene Scher-, Schräg-, Flip- und Skalierungseffekte auf Bilder anzuwenden.


Vorschau des Endergebnisses

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-3D-isometrischen Raum herumzuschwimmen.


Schritt 1: Verschiedene Koordinatenräume

Grafiken werden auf 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 die Koordinatenräume verstehen. Im Allgemeinen verwenden wir nicht nur einen, sondern mehrere Koordinatenräume in einem einzelnen 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.

Coordinate space for stage.

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 wissen, in welchem Bereich Sie sich gerade befinden, beobachten Sie die Leiste unter der Zeitachse der Flash-IDE (siehe Abbildung unten).

Coordinate space for symbol

(Ich verwende Flash CS3, daher kann sich die Position für CS4 und CS5 unterscheiden.) Was ich hervorheben möchte, ist das Vorhandensein unterschiedlicher Koordinatenräume und die Tatsache, dass Sie bereits mit deren Verwendung vertraut sind.


Schritt 2: Die Begründung

Jetzt gibt es einen guten Grund dafür. Wir können einen Koordinatenraum als Referenz verwenden, um den anderen Koordinatenraum zu ändern. Dies mag fremd klingen, daher habe ich die Flash-Präsentation unten eingefügt, um meine Erklärung zu erleichtern. Klicken und ziehen Sie die roten Pfeile. Spielen Sie damit herum.

Im Hintergrund befindet sich ein blaues Gitter und im Vordergrund ein rotes Gitter. Die blauen und roten Pfeile sind anfänglich entlang der x- und y-Achse des Flash-Koordinatenraums ausgerichtet, dessen Mittelpunkt I in die Mitte der Bühne verschoben hat. Das blaue Gitter ist ein Referenzgitter. Die Gitterlinien ä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 Gitter an. Auf dem roten Gitter befinden sich zwei rote Pfeile. Jeder von ihnen gibt die Länge einer Einheit auf der x-Achse und der y-Achse an. Sie bestimmen auch die Ausrichtung des Koordinatenraums. Nehmen wir den roten Pfeil entlang der x-Achse und verlängern Sie ihn so, dass er doppelt so lang ist wie der ursprüngliche Pfeil (blau dargestellt). Beachten Sie die folgenden Bilder.

Original grids without alterationOriginal grids without alterationOriginal grids without alteration
X-axis of red grid altered while blue axis remains unchangedX-axis of red grid altered while blue axis remains unchangedX-axis of red grid altered while blue axis remains unchanged

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


Schritt 3: Affinitätskoordinatenraum

Was ist also ein "affiner Koordinatenraum"? Ich bin sicher, Sie sind vorsichtig genug, um zu beobachten, dass diese Koordinatenräume mit parallelen Gittern gezeichnet werden. Nehmen wir zum Beispiel den roten affinen Raum: Es gibt keine Garantie dafür, dass sowohl die x-Achse als auch die y-Achse immer senkrecht zueinander stehen. Sie können jedoch sicher sein, dass Sie bei jedem Versuch, die Pfeile zu optimieren, niemals zu einem solchen Fall gelangen wie nachstehend.

Not affine spaceNot affine spaceNot affine spaceDieser Koordinatenraum ist kein affiner Koordinatenraum.

Tatsächlich beziehen sich die x- und y-Achsen normalerweise auf den kartesischen Koordinatenraum, wie unten gezeigt.

Cartesian as a type of affine spaceCartesian as a type of affine spaceCartesian as a type of affine space

Beachten Sie, dass das horizontale und das vertikale Gitter senkrecht zueinander stehen. Kartesisch ist eine Art affiner Koordinatenraum, aber wir können ihn nach Belieben in andere affine Räume umwandeln. Das horizontale und das vertikale Gitter müssen nicht unbedingt senkrecht zueinander stehen.

Example of affine spaceExample of affine spaceExample of affine spaceBeispiel eines affinen Koordinatenraums
Example of affine spaceExample of affine spaceExample of affine spaceEin weiteres Beispiel für einen affinen Koordinatenraum

Schritt 4: Affine Transformationen

Wie Sie vielleicht erraten haben, sind die affinen Transformationen Translation, Skalierung, Reflexion, Skewing und Rotation.

Original affine spaceOriginal affine spaceOriginal affine spaceUrsprünglicher affiner Raum
scaled affine spacescaled affine spacescaled affine spaceSkalierter affiner Raum
reflected affine spacereflected affine spacereflected affine spaceReflektierter affiner Raum
skewed affine spaceskewed affine spaceskewed affine spaceVerzerrter affiner Raum
rotated affine spacerotated affine spacerotated affine spaceGedrehter und skalierter affiner Raum

Es ist unnötig zu erwähnen, dass physikalische Eigenschaften wie x, y, scaleX, scaleY und rotation vom Raum abhängen. Wenn wir diese Eigenschaften aufrufen, transformieren wir tatsächlich affine Koordinaten.


Schritt 5: Matrix verstehen

Ich hoffe, dass die oben gezeigten Bilder explizit genug sind, um die Idee nach Hause zu bringen. Dies liegt daran, dass für einen Programmierer, der mit FlashDevelop arbeitet, die Raster nicht angezeigt werden, die die Flash-IDE für Designer bequem anzeigt. All dies muss in deinem Kopf leben.

Abgesehen von der Vorstellung dieser Gitter müssen wir auch die Hilfe der Matrix-Klasse in Anspruch nehmen. Ein mathematisches Verständnis der Matrizen ist daher wichtig, daher werden wir hier die Operationen der Matrix überarbeiten: Addition und Multiplikation.

Matrix operations

Schritt 6: Geometrische Bedeutung der Matrixaddition

Matrixoperationen konvergieren Bedeutungen geometrisch. 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 eine Reihe neuer Orte verschieben. Dies kann durch Matrixaddition erfolgen. Schauen Sie sich das Bild unten an.

Geometrical meaning of matrix additionGeometrical meaning of matrix additionGeometrical meaning of matrix addition

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

Notation of matrix additionNotation of matrix additionNotation of matrix addition

Wir können auch sehen, dass diese Verschiebung tatsächlich unter Verwendung eines Vektors von (tx, ty) dargestellt werden kann. Unterscheiden wir Vektoren und statische Punkte in Koordinatenräumen mithilfe von Klammern und eckigen Klammern. Ich habe sie im Bild unten umgeschrieben.

Notation of matrix addition, differentiatedNotation of matrix addition, differentiatedNotation of matrix addition, differentiated

Schritt 7: ActionScript-Implementierung

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


Schritt 8: Geometrische Bedeutung der Matrixmultiplikation

Die Matrixmultiplikation ist etwas ausgefeilter 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, die dazu führt, lesen Sie die Vorlesungsreihe des Professors.

Beginnen wir mit dem Fall der Identitätsmatrix I.

Identity matrixIdentity matrixIdentity matrix

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

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

Vector formVector formVector form

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

Interpretation of vector formInterpretation of vector formInterpretation of vector form

Aus dem kartesischen Gitter (linkes Gitter) können wir sehen, dass sich der blaue Punkt bei (2, 1) befindet. Wenn wir nun dieses ursprüngliche Gitter von x und y gemäß einer Reihe von Vektoren (unter dem rechten Gitter) in ein neues Gitter (rechtes Gitter) umwandeln, wird der blaue Punkt auf dem neuen Gitter auf (2, 1) verschoben - aber wenn wir dies wieder dem ursprünglichen Raster zuordnen, ist es der gleiche Punkt wie zuvor.

Da wir das ursprüngliche Gitter in ein anderes Gitter umwandeln, das dieselben Vektoren für x und y verwendet, sehen wir keinen Unterschied. Tatsächlich sind die Änderungen von x und y bei dieser Transformation gleich Null. Dies ist aus geometrischer Sicht mit Identitätsmatrix gemeint.

Wenn wir jedoch versuchen, ein Mapping mit anderen Transformationen durchzuführen, werden wir einen Unterschied feststellen. Ich weiß, dass dies zunächst nicht das aufschlussreichste Beispiel war. Fahren wir also mit einem anderen Beispiel fort.


Schritt 9: Skalieren entlang X.

Scaling in x directionScaling in x directionScaling in x direction

Das Bild oben zeigt eine Skalierung des Koordinatenraums. Überprüfen Sie den Vektor von x im transformierten Koordinatenraum: Eine Einheit des transformierten x macht zwei Einheiten des ursprünglichen x aus. Auf dem transformierten Koordinatenraum ist die Koordinate des blauen Punktes 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. Jetzt habe ich ihre jeweiligen Bedeutungen hinzugefügt.

Interpretation of matrix

Schauen Sie sich nun das numerische Ergebnis unseres Skalierungsbeispiels an.

  • 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)
Scale numerical result

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


Schritt 10: ActionScript-Implementierung

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


Schritt 11: Skalieren von X und Y.

scaling x and yscaling x and yscaling x and y

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

Und um das Ergebnis numerisch zu bestätigen...

Scale x and y numerical result

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

(Beachten Sie, dass die Dehnungsrichtung von y nach unten und nicht nach oben ist, da y im Flash nach unten, aber im normalen kartesischen Koordinatenraum, den ich im Diagramm verwendet habe, nach oben erhöht wird.)


Schritt 12: Reflexion

reflectionreflectionreflection

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

reflect x numerical result

Die ActionScript-Implementierung ist dieselbe wie zuvor, verwendet jedoch stattdessen die folgenden 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.

Was ist als nächstes mit der gleichzeitigen Reflexion über x und y? Schauen Sie sich das Bild unten an.

reflectionreflectionreflection

Auch numerisch im Bild unten berechnet.

reflect x and y numerical result

Für die ActionScript-Implementierung... Nun, ich bin sicher, Sie kennen die Werte, 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 unten aufgenommen.


Schritt 13: Schrägstellen und Scheren

Das Verdrehen bringt ein wenig Spaß mit sich. Für den Fall des folgenden Bildes wurde die x-Achse des transformierten Gitters neu ausgerichtet und skaliert. Vergleichen Sie die roten Pfeile in beiden Gittern unten: Sie sind unterschiedlich, aber die y-Achse bleibt unverändert.

skewingskewingskewingSchrägstellung

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

Numerisch passiert genau das...

shear in y numerical result

In Bezug auf die Implementierung habe ich die folgenden Verbesserungen aufgelistet.

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

Ich bin mir sicher, dass Sie an dieser Stelle die Dinge selbst ausprobieren möchten, also machen Sie weiter und optimieren Sie sie

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

Ich habe die Flash-Ausgabe für beide Fälle wie folgt eingefügt. Für Leser, die Hilfe bei diesen Werten benötigen, lesen Sie Multiplication_final.as im Quelldownload.


Schritt 14: Drehung

Ich betrachte Rotation als eine Teilmenge von Schrägstellung. 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.

rotation explained

ActionScript bietet dazu eine Methode in der Matrix-Klasse rotate(). Aber lassen Sie uns das trotzdem durchgehen.

Jetzt wollen wir die Größe einer Längeneinheit in x und y nicht vom ursprünglichen Gitter ändern. nur um die Ausrichtung von jedem zu ändern. Wir können die Trigonometrie verwenden, um zu dem im obigen Bild gezeigten Ergebnis zu gelangen. Bei einem gegebenen Winkel a erhalten wir das gewünschte Ergebnis, indem wir die Vektoren (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 beträgt weiterhin eine Einheit, aber jede Achse befindet sich im Vergleich zu den Originalen in einem Winkel von a.

Nehmen Sie für die Implementierung von Actionscript unter der Annahme, dass der Winkel a 45 Grad beträgt (dh 0,25 * Pi-Bogenmaß), die Matrixwerte wie folgt an:

Auf die vollständige Quelle kann in Multiplication_final.as verwiesen werden.


Schritt 15: Anwendung

Eine Vektorinterpretation einer 2x2-Matrix eröffnet uns Raum zum Erkunden. Die Anwendung zum Bearbeiten von Bitmaps (BitmapData, LineBitmapStyle, LineGradientStyle usw.) 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 so aussieht, als würde es tatsächlich in 3D umgedreht.

view of isometric worldAnsicht einer pseudo-3D-isometrischen Welt

Aus dem obigen Bild können wir ersehen, dass in einer Welt mit einer isometrischen Ansicht jede Grafik, die "steht", ihren y-Achsenvektor unverändert lässt, während sich der x-Achsenvektor dreht. Beachten Sie, dass sich eine Längeneinheit für die x- und y-Achse nicht ändert. Mit anderen Worten, auf beiden Achsen sollte keine Skalierung erfolgen, sondern nur eine Drehung um die x-Achse.

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 den Fischversatz zu sehen. Lassen Sie los, um Ihre Interaktion zu beenden.

Hier ist das wichtige Stück Actionscript. Ich habe die entscheidenden Linien hervorgehoben, die die Drehung der x-Achse behandeln. Sie können auch auf FakeIso.as verweisen.

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


Schritt 16: Tastatursteuerung hinzufügen

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

Bei einem Tastendruck dreht sich velo:

Jetzt werden wir für jeden Rahmen versuchen, die Vorderseite des Fisches zu färben und den Fisch ebenfalls zu verzerren. Wenn die Geschwindigkeit velo eine Größe von mehr als 1 hat und wir sie auf die Fischmatrix m anwenden, erhalten wir auch einen Skalierungseffekt. Um diese Möglichkeit auszuschließen, werden wir die Geschwindigkeit normalisieren und dann nur anwenden das zur Matrix des Fisches.


Schritt 17: Ihr Fisch

Klicken Sie auf die Bühne und drücken Sie dann die linke und rechte Pfeiltaste, um zu sehen, wie der Fisch die Richtung ändert.


Schritt 18: Eine weitere Tastatursteuerung

Lassen Sie uns zum Aufpeppen auch die Steuerung des y-Achsenvektors zulassen.

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


Schritt 19: Ihr nicht so normaler Fisch

Nun, für einige mag sich das Ergebnis der Steuerung beider Achsen als etwas verwirrend erweisen, aber der Punkt ist, dass Sie Ihren Fisch jetzt verzerren, übersetzen, reflektieren und sogar drehen können! Probieren Sie die Kombinationen von oben + links, oben + rechts, unten + links, unten + rechts aus.

Überprüfen Sie auch, ob Sie die "Vorderseite" des Fisches beibehalten können (der Fisch wird grau). Tipp: Tippen Sie kontinuierlich nach oben, dann nach links, dann nach unten und dann nach rechts. Du machst eine Rotation!

Abschluss

Ich hoffe, Sie finden Matrixmathematik nach dem Lesen dieses Artikels eine wertvolle Bereicherung für Ihre Projekte. Ich hoffe, dass ich in kleinen Quick Tips, die aus diesem Artikel hervorgehen, und in Matrix3d, das für 3D-Manipulationen unerlässlich ist, etwas mehr über Anwendungen der 2x2-Matrix schreiben kann. Danke für das Lesen, terima kasih.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.