3D flex, girar em torno de um ponto aleatório para um recipiente (com solução parcial!)

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

Pergunta

Estou tentando encontrar a melhor maneira de rodar um recipiente (ou qualquer coisa para que o assunto), utilizando o matrix3D recursos do Flash 10 para flex.

Eu consegui obter um recipiente para girar em torno de um ponto que não é seu ponto de registro, mas eu só conseguiu isso por desligar o recorte em um recipiente, em seguida, colocar o conteúdo em algum lugar diferente (0,0,0) . Isto funciona, mas não é muito intuitivo e suga ao tentar colocar vários itens ou mesmo se você precisa mover o ponto de rotação.

Usando a classe matrix3D parece ser o caminho a percorrer, mas eu não sei exatamente como.

Felicidades

Informações adicionais - Se o meu recipiente está em (0,0,0) no palco e gostaria de girar em torno do X coord meio do recipiente, em seguida, eu traduzo por container.width / 2 para o X, em seguida, girar e traduzir novamente. Isso funciona bem. Mas se a minha recipiente é exemplo em (10, 0, 0), então se eu traduzir o mesmo que acima e adicione o extra de 10, em seguida, ele não funciona.

soloution (que é uma besteira completa - por favor, explique se você puder) Como foi sugerido que você precisa para traduzir, girar, então -traslate. Eu sabia disso, mas nunca funcionou.
Mas veja o soloution abaixo, eu não entendo. (Painel é o objecto que estou rotativo, chamo função tanto ())

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

Solução 2

OK, a solução seria -

1 - criar seu próprio componente com vars para o original X, Y, Z e largura e altura. Estes serão usados ??para convenence para salvar as operações da matriz extra. Por exemplo estender a classe Box e apenas adicionar aqueles var para a nova classe.

2 - Adicione componente de aplicativo, algo como o abaixo. (Os valores orig são porque o real x, y, z assim por diante vai mudar durante a rotação, mas você precisa valores orig para calcular a rotação correta.

<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 - usar o código a seguir ao girar, chamada na acima evento enterFrame

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 - é isso. Este vai rodar em torno do ponto central, sobre o eixo Y. Alterar os valores de deslocamento para diferentes pontos de rotação.

Atualização Como apontado você não precisa mover as chamadas em função separada, mas você vai precisar usar o acima de modo que você pode obter com a largura original, altura, x e y (fornecendo o seu não é difícil de codificação todos os valores)

Outras dicas

Rotação matrizes sempre girar em torno da origem.

A rotação de um objeto em torno de um P ponto arbitrário geralmente requer:

  1. tradução do objeto por -P
  2. rotação do objeto, conforme necessário
  3. tradução do objeto por P

Você considerou simplesmente movendo o vector pivot?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top