Durchführen komplexer 3D-Transformationen

Flash Player 10 und höher, Adobe AIR 1.5 und höher

Die Matrix3D-Klasse ermöglicht Ihnen die Transformation von 3D-Punkten innerhalb eines Koordinatenraums oder die Abbildung von 3D-Punkten von einem Koordinatenraum auf einen anderen.

Sie brauchen keine Matrizenrechnung zu beherrschen, um mit der Matrix3D-Klasse zu arbeiten. Die meisten der gebräuchlichen Transformationsoperationen können mithilfe der Methoden dieser Klasse durchgeführt werden. Sie brauchen die Werte der einzelnen Elemente in der Matrix nicht explizit einzustellen oder zu berechnen.

Nachdem Sie die z -Eigenschaft eines Anzeigeobjekts auf einen numerischen Wert gesetzt haben, können Sie mithilfe der Matrix3D-Eigenschaft des Transform-Objekts des Anzeigeobjekts die Transformationsmatrix des Objekts abrufen:

var leafMatrix:Matrix3D = this.transform.matrix3D;

Mithilfe der Methoden des Matrix3D-Objekts können Sie eine Versetzung, Drehung, Skalierung und perspektivische Projektion an dem Anzeigeobjekt durchführen.

Verwenden Sie die Vector3D-Klasse mit ihren Eigenschaften x , y und z für die Verwaltung von 3D-Punkten. Die Klasse kann auch einen räumlichen Vektor in der Physik repräsentieren, der eine bestimmte Richtung und Größe besitzt. Die Methoden der Vector3D-Klasse ermöglichen die Durchführung allgemeiner Berechnungen mit räumlichen Vektoren wie Addition, Skalarprodukt oder Kreuzprodukt (auch Vektorprodukt).

Hinweis: Die Vector3D-Klasse ist nicht mit der ActionScript-Klasse „Vector“ verwandt. Die Vector3D-Klasse umfasst Eigenschaften und Methoden für die Definition und Bearbeitung von 3D-Punkten, während die Vector-Klasse Arrays typisierter Objekte unterstützt.

Erstellen von Matrix3D-Objekten

Für das Erstellen oder Abrufen von Matrix3D -Objekten gibt es drei vorrangige Verfahren:

  • Verwenden der Matrix3D() -Konstruktormethode zur Instanziierung einer neuen Matrix. Der Matrix3D() -Konstruktor akzeptiert ein Vector -Objekt mit 16 numerischen Werten und setzt jeden dieser Werte in eine Zelle der Matrix ein. Zum Beispiel:

    var rotateMatrix:Matrix3D = new Matrix3D(1,0,0,1, 0,1,0,1, 0,0,1,1, 0,0,0,1);
  • Festlegen des Wertes der z -Eigenschaft eines Anzeigeobjekts und anschließendes Abrufen der Transformationsmatrix aus der transform.matrix3D -Eigenschaft dieses Objekts.

  • Abrufen des Matrix3D-Objekts, das die Anzeige von 3D-Objekten auf der Bühne steuert, indem die Methode perspectiveProjection.toMatrix3D() des Stammanzeigeobjekts abgerufen wird.

Anwenden mehrfacher 3D-Transformationen

Mit einem Matrix3D-Objekt können Sie mehrere 3D-Transformationen gleichzeitig anwenden. Wenn Sie beispielsweise einen Würfel drehen, skalieren und dann verschieben wollen, könnten Sie alle drei Transformationen gesondert auf jeden Punkt des Würfels anwenden. Allerdings ist es sehr viel effizienter, mehrere Transformationen in einem Matrix3D-Objekt vorauszuberechnen und dann eine Matrixtransformation auf jeden der Punkte anzuwenden.

Hinweis: Dabei ist die Reihenfolge wichtig, in der die Matrixtransformationen angewendet werden. Matrixberechnungen sind nicht kommutativ. Wenn beispielsweise erst eine Drehung und dann eine Versetzung angewendet wird, entsteht ein anderes Ergebnis als wenn Sie erst dieselbe Versetzung und danach dieselbe Drehung anwenden.

Im folgenden Beispiel werden zwei Wege aufgezeigt, um mehrere 3D-Transformationen durchzuführen.

package { 
    import flash.display.Sprite;     
    import flash.display.Shape; 
    import flash.display.Graphics; 
    import flash.geom.*; 
 
public class Matrix3DTransformsExample extends Sprite 
    { 
        private var rect1:Shape; 
        private var rect2:Shape; 
         
public function Matrix3DTransformsExample():void 
        { 
            var pp:PerspectiveProjection = this.transform.perspectiveProjection; 
            pp.projectionCenter = new Point(275,200); 
            this.transform.perspectiveProjection = pp; 
             
            rect1 = new Shape(); 
            rect1.x = -70; 
            rect1.y = -40; 
            rect1.z = 0; 
            rect1.graphics.beginFill(0xFF8800); 
            rect1.graphics.drawRect(0,0,50,80); 
            rect1.graphics.endFill(); 
            addChild(rect1); 
 
            rect2 = new Shape(); 
            rect2.x = 20; 
            rect2.y = -40; 
            rect2.z = 0; 
            rect2.graphics.beginFill(0xFF0088); 
            rect2.graphics.drawRect(0,0,50,80); 
            rect2.graphics.endFill(); 
            addChild(rect2); 
             
            doTransforms(); 
        } 
 
        private function doTransforms():void 
        { 
            rect1.rotationX = 15; 
            rect1.scaleX = 1.2; 
            rect1.x += 100; 
            rect1.y += 50; 
            rect1.rotationZ = 10; 
 
            var matrix:Matrix3D = rect2.transform.matrix3D; 
            matrix.appendRotation(15, Vector3D.X_AXIS); 
            matrix.appendScale(1.2, 1, 1); 
            matrix.appendTranslation(100, 50, 0); 
            matrix.appendRotation(10, Vector3D.Z_AXIS); 
            rect2.transform.matrix3D = matrix; 
        } 
    } 
}

In der doTransforms() -Methode verwendet der erste Codeblock die DisplayObject-Eigenschaften zum Ändern der Drehung, Skalierung und Position eines Rechtecks. Der zweite Codeblock verwendet die Methoden der Matrix3D-Klasse, um dieselben Transformationen durchzuführen.

Der wichtigste Vorteil beim Verwenden der Matrix3D -Methoden liegt darin, dass alle Berechnungen zuerst in der Matrix stattfinden. Anschließend werden sie nur einmal auf das Anzeigeobjekt angewendet, wenn seine transform.matrix3D -Eigenschaft gesetzt ist. Die Einstellung der DisplayObject-Eigenschaften macht das Lesen des Quellcodes etwas einfacher. Allerdings sind jedes Mal, wenn eine Dreh- oder Skalierungseigenschaft gesetzt wird, mehrere Berechnungen und Änderungen an mehreren Anzeigeobjekteigenschaften erforderlich.

Wenn Ihr Code dieselben komplexen Transformationen an Anzeigeobjekten mehrmals vornimmt, sollten Sie das Matrix3D-Objekt als Variable speichern und dann immer wieder anwenden.

Verwenden von 3DMatrix-Objekten zur Neuanordnung der Anzeige

Wie bereits weiter vorne erwähnt, bestimmt die Reihenfolge der Ebenen in der Anzeigeliste die Anzeigereihenfolge, ungeachtet ihrer relativen z-Achsen. Wenn Ihre Animation die Eigenschaften von Anzeigeobjekten in einer Reihenfolge transformiert, die von der Reihenfolge in der Anzeigeliste abweicht, kann es passieren, dass der Betrachter eine Anordnung gemäß der Anzeigeliste sieht, die der z-Achsenanordnung widerspricht. Das bedeutet, dass ein Objekt, das weiter entfernt vom Betrachter angezeigt werden sollte, vor einem Objekt erscheint, das näher beim Betrachter liegt.

Um sicherzustellen, dass die Anordnung von dreidimensionalen Anzeigeobjekten der relativen Tiefe der Objekte entspricht, sollten Sie einen Ansatz wie den folgenden beachten:

  1. Verwenden Sie die getRelativeMatrix3D() -Methode des Transform-Objekts, um die relativen z-Achsen des untergeordneten 3D-Anzeigeobjekts abzurufen.

  2. Entfernen Sie die Objekte mithilfe der removeChild() -Methode aus der Anzeigeliste.

  3. Sortieren Sie die Anzeigeobjekte aufgrund ihrer relativen z-Achsenwerte.

  4. Fügen Sie die untergeordneten Objekte mithilfe der addChild() -Methode in umgekehrter Reihenfolge wieder in die Anzeigeliste ein.

Diese Neuanordnung stellt sicher, dass Ihre Objekte in Übereinstimmung mit den relativen z-Achsen angezeigt werden.

Im folgenden Code wird die korrekte Anzeige der sechs Flächen eines Quaders erzwungen. Die Flächen des Quaders werden neu angeordnet, nachdem Drehungen darauf angewendet worden sind.

public var faces:Array; . . . 
 
public function ReorderChildren() 
{     
    for(var ind:uint = 0; ind < 6; ind++) 
    { 
        faces[ind].z = faces[ind].child.transform.getRelativeMatrix3D(root).position.z; 
        this.removeChild(faces[ind].child); 
    } 
    faces.sortOn("z", Array.NUMERIC | Array.DESCENDING); 
    for (ind = 0; ind < 6; ind++) 
    { 
        this.addChild(faces[ind].child); 
    } 
}

Die Anwendungsdateien für dieses Beispiel finden Sie unter www.adobe.com/go/learn_programmingAS3samples_flash_de . Die Anwendungsdateien befinden sich im Ordner „Samples/ReorderByZ “.