Flex 3D, rotation autour d'un point aléatoire pour un conteneur (avec solution partielle!)

StackOverflow https://stackoverflow.com/questions/627087

Question

J'essaie de trouver le meilleur moyen de faire pivoter un conteneur (ou quoi que ce soit d'autre) en utilisant les fonctionnalités matrix3D de flash 10 pour flex.

J'ai réussi à faire pivoter un conteneur autour d'un point qui n'est pas son point d'enregistrement, mais je n'y suis parvenu qu'en désactivant le découpage sur un conteneur, puis en plaçant le contenu ailleurs que (0,0,0) . Cela fonctionne, mais ce n’est pas très intuitif et ça craint lorsque vous essayez de placer plusieurs éléments ou même si vous devez déplacer le point de rotation.

Utiliser la classe matrix3D semble être la voie à suivre, mais je ne sais pas exactement comment.

A bientôt

Informations complémentaires - Si mon conteneur est à (0,0,0) sur la scène et que je souhaite pivoter autour de la coordonnée X centrale du conteneur, je traduis par conteneur.width / 2 pour le X, puis effectue une rotation et une traduction. Cela fonctionne bien. MAIS si mon conteneur est dit à (10, 0, 0), alors si je traduis la même chose que ci-dessus et que j'ajoute le 10 supplémentaire, cela ne fonctionnera pas.

Soloution (qui est un déchet complet - veuillez expliquer si vous le pouvez) Comme il a été suggéré, vous devez traduire, faire pivoter, puis -traslate. Je le savais mais cela n'a jamais fonctionné.
MAIS voir la solution ci-dessous, je ne comprends pas. (le panneau est l’objet que je tourne, j’appelle function both ())

private function rotateOnly() : void {
        panel.transform.matrix3D.appendRotation(36, Vector3D.Y_AXIS);
}

private var valueToMove : Number = 300;
private var translateUpOrDown : Boolean = false;
private function translateOnly() : void {
    if(translateUpOrDown){
            panel.transform.matrix3D.appendTranslation(valueToMove, 0, 0);
    translateUpOrDown = false;
} else {
    panel.transform.matrix3D.appendTranslation(-valueToMove, -0,0);
    translateUpOrDown = true;
}
 }

 //I do not run both chunks of code here at once, this is only to show what I've tried   
 private function both() : void {
     //IF I call this function and call this chunk then the rotation works
        translateOnly();
        rotateOnly();
        translateOnly(); 


     //If I call this chunk which does the exact same as the above it does NOT work!!
        panel.transform.matrix3D.appendTranslation(valueToMove, 0,0);
panel.transform.matrix3D.appendRotation(36, Vector3D.Y_AXIS);
panel.transform.matrix3D.appendTranslation(-valueToMove, 0,0); 
 }
Était-ce utile?

La solution 2

OK, la solution serait -

1 - créez votre propre composant avec vars pour le X, Y, Z, la largeur et la hauteur d'origine. Celles-ci seront utilisées à des fins de commodité pour enregistrer des opérations de matrice supplémentaires. E.G étendre la classe Box et ajouter ces variables à la nouvelle classe.

2 - ajoutez un composant à l'application, comme ci-dessous. (Les valeurs orig sont dues au fait que les x, y, z ainsi de suite vont changer pendant la rotation, mais vous devez utiliser des valeurs orig pour calculer la rotation correcte.

<local:RotationContainer 
        id="movingBox" 
        width="50"
        origWidth="50"
        height="60"
        origHeight="60"
        x="80"
        origX="80"
        y="70"
        origY="70"
        z="0"
        origZ="0"
        enterFrame="rotateObject(event)"
        />

3 - utilisez le code suivant lors de la rotation, appelez l'événement enterFrame ci-dessus

private var translateUpOrDown : Boolean = false;
        private function translateOnly(obj : Object, valueToMoveX : Number,  valueToMoveY : Number) : void {

            if(translateUpOrDown){
                obj.transform.matrix3D.appendTranslation(valueToMoveX, valueToMoveY, 0);
                translateUpOrDown = false;
            } else {
                obj.transform.matrix3D.appendTranslation(-valueToMoveX, -valueToMoveY, 0);
                translateUpOrDown = true;
            }
        }

        private function rotateOnly(obj : Object) : void {
            obj.transform.matrix3D.appendRotation(rotationAmount, Vector3D.Y_AXIS);
        }

        private function rotateObject(event : Event) : void {

            var offsetX : Number = (event.currentTarget.origWidth / 2) + event.currentTarget.origX;
            var offsetY : Number = (event.currentTarget.origHeight / 2) + event.currentTarget.origY;

            translateOnly(event.currentTarget, offsetX, offsetY);
            rotateOnly(event.currentTarget);
            translateOnly(event.currentTarget, offsetX, offsetY);
        }

4 - c'est tout. Cela tournera autour du point central, sur l’axe des Y. Modifiez les valeurs de décalage pour différents points de rotation.

MISE À JOUR Comme indiqué, vous n’avez pas besoin de déplacer les appels dans une fonction distincte, mais vous devrez utiliser ce qui précède afin d’obtenir la largeur, la hauteur, les dimensions x et amp; originales. y (à condition de ne pas coder en dur toutes les valeurs)

Autres conseils

Les matrices de rotation pivotent toujours autour de l'origine.

La rotation d'un objet autour d'un point arbitraire P nécessite généralement:

  1. traduction de l'objet par -P
  2. rotation de l'objet selon les besoins
  3. traduction de l'objet par P

avez-vous envisagé de déplacer simplement le vecteur pivot?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top