Flex 3D, gire alrededor de un punto aleatorio para un contenedor (¡con solución parcial!)

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

Pregunta

Estoy tratando de encontrar la mejor manera de rotar un contenedor (o cualquier otra cosa) usando las funciones de matrix3D en flash 10 para flex.

He logrado que un contenedor gire alrededor de un punto que no es su punto de registro, pero solo he logrado esto apagando el recorte en un contenedor y luego colocando el contenido en otro lugar que no sea (0,0, 0). Esto funciona, pero no es muy intuitivo y apesta cuando intenta colocar varios elementos o incluso si necesita mover el punto de rotación.

Usar la clase matrix3D parece ser el camino a seguir, pero no estoy seguro exactamente cómo.

Saludos

Información adicional - Si mi contenedor está en (0,0,0) en el escenario y deseo rotar alrededor de la coordenada X central del contenedor, traduzco por container.width / 2 para la X y luego giro y traduzco nuevamente. Esto funciona bien PERO si mi contenedor está en (10, 0, 0), si traduzco lo mismo que el anterior y agrego los 10 adicionales, entonces no funciona.

Solución (que es basura completa, explique si puede) Como se ha sugerido, necesita traducir, rotar y luego traducir. Lo sabía pero nunca funcionó.
PERO ver la solución a continuación, no lo entiendo. (el panel es el objeto que estoy rotando, llamo función ambos ())

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); 
 }
¿Fue útil?

Solución 2

OK, la solución sería -

1: cree su propio componente con variables para la X, Y, Z original y ancho y alto. Estos se usarán por conveniencia para ahorrar operaciones de matriz adicionales. E.G extiende la clase Box y solo agrega esas var a la nueva clase.

2: agregue un componente a la aplicación, algo como lo siguiente. (los valores de origen se deben a que los valores reales de x, y, z, etc. cambiarán durante la rotación, pero necesita valores de origen para calcular la rotación correcta.

<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 - use el siguiente código al rotar, llame al evento enterFrame anterior

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 - eso es todo. Esto rotará alrededor del punto central, en el eje Y. Cambie los valores de desplazamiento para diferentes puntos de rotación.

ACTUALIZACIÓN Como se señaló, no es necesario mover las llamadas a una función separada, pero deberá usar lo anterior para poder obtener el ancho, la altura, x & amp; y (siempre que no esté codificando todos los valores)

Otros consejos

Las matrices de rotación siempre giran alrededor del origen.

La rotación de un objeto alrededor de un punto arbitrario P generalmente requiere:

  1. traducción del objeto por -P
  2. rotación del objeto según sea necesario
  3. traducción del objeto por P

¿ha considerado simplemente mover el vector pivote?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top