Complexe 3D-transformaties uitvoeren

Flash Player 10 of hoger, Adobe AIR 1.5 of hoger

Met de klasse Matrix3D kunt u 3D-punten in een coördinaatruimte transformeren of 3D-punten van een coördinaatruimte toewijzen aan een andere coördinaatruimte.

U hoeft de wiskunde achter de matrix niet te begrijpen om de klasse Matrix3D te gebruiken. De meeste algemene transformatiebewerkingen kunnen worden afgehandeld met de methoden van de klasse. U hoeft zich geen zorgen te maken over het expliciet instellen of berekenen van de waarden van elk element in de matrix.

Nadat u de eigenschap z van een weergaveobject hebt ingesteld op een numerieke waarde, kunt u de transformatiematrix van het object ophalen met de eigenschap Matrix3D van het Transform-object van het weergaveobject:

var leafMatrix:Matrix3D = this.transform.matrix3D;

U kunt de methoden van het Matrix3D-object gebruiken om translatie, rotatie, schaling en perspectiefprojectie toe te passen op het weergaveobject.

Gebruik de klasse Vector3D met de eigenschappen x , y en z voor het beheer van 3D-punten. De klasse kan ook een ruimtelijke vector in fysica representeren met een richting en een magnitude. Met de methoden van de klasse Vector3D kunt u algemene berekeningen met ruimtelijke vectoren uitvoeren, zoals optellen, scalair product en kruisproduct.

Opmerking: De klasse Vector3D is niet gerelateerd aan de ActionScript-klasse Vector. De klasse Vector3D bevat eigenschappen en methoden voor het vastleggen en bewerken van 3D-punten, terwijl de klasse Vector arrays van objecten met een bepaald type ondersteunt.

Matrix3D-objecten maken

Er zijn drie manieren om Matrix3D -objecten te maken of op te halen:

  • Gebruik de constructormethode Matrix3D() om een nieuwe matrix te instantiëren. De constructor Matrix3D() neemt een Vector -object dat 16 numerieke waarden bevat, en plaatst elke waarde in een cel van de matrix. Bijvoorbeeld:

    var rotateMatrix:Matrix3D = new Matrix3D(1,0,0,1, 0,1,0,1, 0,0,1,1, 0,0,0,1);
  • Stel de eigenschap z van een weergaveobject in. Haal vervolgens de transformatiematrix van de eigenschap transform.matrix3D van dat object op.

  • Haal het Matrix3D-object op dat de weergave van 3D-objecten op het werkgebied regelt door de perspectiveProjection.toMatrix3D() -methode van het hoofdweergaveobject aan te roepen.

Meerdere 3D-transformaties toepassen

U kunt een groot aantal 3D-transformaties tegelijk toepassen met behulp van een Matrix3D-object. U wilt bijvoorbeeld een kubus roteren, schalen en vervolgens verplaatsen. U kunt dan drie afzonderlijke transformaties toepassen op elk punt van de kubus. Het is echter efficiënter om meerdere transformaties vooraf te berekenen in één Matrix3D-object en vervolgens één matrixtransformatie uit te voeren op elk punt.

Opmerking: De volgorde waarin matrixtransformaties worden toegepast, is van belang. Matrixberekeningen zijn niet verwisselbaar. Een rotatie gevolgd door een translatie, heeft bijvoorbeeld een ander resultaat dan dezelfde translatie gevolgd door dezelfde rotatie.

In het volgende voorbeeld worden twee manieren getoond om meerdere 3D-transformaties uit te voeren.

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 de methode doTransforms() gebruikt het eerste codeblok de DisplayObject-eigenschappen om de rotatie, schaling en positie van een rechthoekige vorm te wijzigen. Het tweede codeblok gebruikt de methoden van de klasse Matrix3D om dezelfde transformaties uit te voeren.

Het grootste voordeel van de methoden van Matrix3D is dat alle berekeningen eerst in de matrix worden uitgevoerd. Vervolgens worden ze maar één keer op het weergaveobject toegepast wanneer de eigenschap transform.matrix3D wordt ingesteld. Door het instellen van de DisplayObject-eigenschappen wordt de broncode iets eenvoudiger om te lezen. Maar elke keer dat een rotatie- of schalingseigenschap wordt ingesteld, moeten er meerdere berekeningen worden uitgevoerd en weergaveobjecteigenschappen worden gewijzigd.

Als uw code dezelfde complexe transformaties meerdere keren toepast op weergaveobjecten, kunt u het Matrix3D-object als variabele opslaan en vervolgens zo vaak als nodig opnieuw toepassen.

Matrix3D-objecten gebruiken om de weergavevolgorde te wijzigen

Zoals eerder vermeld, bepaalt de laagvolgorde van weergaveobjecten in de weergavelijst de volgorde waarin lagen worden weergegeven, ongeacht hun relatieve z-as. Als uw animatie de eigenschappen van weergaveobjecten verandert in een volgorde die afwijkt van de volgorde in de weergavelijst, ziet de kijker mogelijk een laagwerking van weergaveobjecten die niet overeenkomt met de laagwerking van de z-as. Een object dat ver weg van de kijker moet lijken, wordt dan mogelijk weergegeven vóór een object dat dichterbij de kijker is.

Als u zeker wilt weten dat de laagvolgorde van 3D-weergaveobjecten overeenkomt met de relatieve diepte van de objecten, gebruikt u een werkwijze als de volgende:

  1. Haal met de methode getRelativeMatrix3D() van het Transform-object de relatieve z-assen van de onderliggende 3D-weergaveobjecten op.

  2. Verwijder met de methode removeChild() de objecten uit de weergavelijst.

  3. Sorteer de weergaveobjecten op basis van de relatieve waarde van de z-as.

  4. Voeg met de methode addChild() de onderliggende objecten in omgekeerde volgorde weer toe aan de weergavelijst.

Deze nieuwe volgorde zorgt dat de objecten worden weergegeven in overeenstemming met de relatieve z-as.

De volgende code dwingt de correcte weergave van de zes vlakken van een 3D-vak af. De vlakken van het vak worden opnieuw geordend nadat er rotaties op zijn toegepast:

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); 
    } 
}

Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. U vindt de toepassingsbestanden in de map Samples/ReorderByZ.