If you're seeing this message, it means we're having trouble loading external resources on our website.

Se você está atrás de um filtro da Web, certifique-se que os domínios *.kastatic.org e *.kasandbox.org estão desbloqueados.

Conteúdo principal

Rotacionando formas 3D

Girar coisas em três dimensões soa complicado e, às vezes, pode ser, mas há rotações simples. Por exemplo, se nos imaginarmos girando nosso cubo em torno do eixo z (perpendicular à tela), estaríamos na verdade simplesmente rodando um quadrado em duas dimensões:

Uma razão para aprender trigonometria

Diagrama de triângulo
Podemos simplificar ainda mais as coisas olhando para um único nó na posição (x, 0). Usando trigonometria simples, podemos descobrir que a posição do ponto, após girá-lo θ em torno da origem, é:
x=x×cos(θ)
y=x×sen(θ)
Se você não entende de onde estas equações vieram, este vídeo pode ajudar.

Rotação de um ponto em relação à origem

Diagrama de triângulo
O exemplo acima nos permite girar um ponto no eixo x em relação à origem. Mas e se ele não estiver no eixo x? Isso requer trigonometria um pouco mais avançada. Se chamarmos a distância entre o ponto (x, y) e a origem de r, e o ângulo entre a linha para (x, y) e o eixo x de α, então:
x=r×cos(α)y=r×sen(α)
Se girarmos mais β até o ponto (x', y'), então:
x=r×cos(α+β)y=r×sen(α+β)
Usando algumas identidades trigonométricas, temos:
x=r×cos(α)cos(β)r×sen(α)sen(β)y=r×sen(α)cos(β)+r×cos(α)sen(β)
Substituindo os valores de x e y acima, temos uma equação para as novas coordenadas como uma função das coordenadas antigas e do ângulo de rotação:
x=x×cos(β)y×sen(β)y=y×cos(β)+x×sen(β)

Como escrever uma função de rotação

Agora que sabemos a matemática envolvida, podemos escrever uma função para girar um nó ou, melhor ainda, nosso array de nós, em torno do eixo z. Esta função vai iterar por cada nó no array, encontrar suas coordenadas x e y atuais e atualizá-las. Armazenamos sin(teta) e cos(teta) fora do loop para que só precisemos calculá-los uma vez:
var rotateZ3D = function(theta) {
   var sinTheta = sin(theta);
   var cosTheta = cos(theta);
   for (var n = 0; n < nodes.length; n++) {
      var node = nodes[n];
      var x = node[0];
      var y = node[1];
      node[0] = x * cosTheta - y * sinTheta;
      node[1] = y * cosTheta + x * sinTheta;
   }
};
Para girar o cubo 30 graus, chamaremos a função da seguinte forma:
rotateZ3D(30);
Você pode ver o cubo rotacionado abaixo - ficou um pouco mais interessante, mas não muito:

Rotação em três dimensões

Agora, já sabemos girar nosso cubo em duas dimensões, mas ele ainda se parece com um quadrado. E se quiséssemos girar o nosso cubo no eixo y (vertical)? Se nos imaginarmos olhando o cubo de cima conforme o giramos no eixo y, veríamos um quadrado rodando, tal qual ocorre quando o giramos em torno do eixo z.
Podemos usar a trigonometria e a função de antes e simplesmente renomear o eixo, de modo que o eixo z se torne o eixo y. Neste caso, as coordenadas y do nó não mudariam, apenas as x e z:
var rotateY3D = function(theta) {
   var sinTheta = sin(theta);
   var cosTheta = cos(theta);
   for (var n = 0; n < nodes.length; n++) {
      var node = nodes[n];
      var x = node[0];
      var z = node[2];
      node[0] = x * cosTheta - z * sinTheta;
      node[2] = z * cosTheta + x * sinTheta;
   }
};
E podemos usar o mesmo argumento para criar uma função que gira nosso cubo ao redor do eixo x:
var rotateX3D = function(theta) {
   var sinTheta = sin(theta);
   var cosTheta = cos(theta);
   for (var n = 0; n < nodes.length; n++) {
      var node = nodes[n];
      var y = node[1];
      var z = node[2];
      node[1] = y * cosTheta - z * sinTheta;
      node[2] = z * cosTheta + y * sinTheta;
   }
};
Agora que temos essas funções definidas, podemos girar 30 graus nos outros dois eixos:
rotateX3D(30);
rotateY3D(30);
Você pode ver o código completo abaixo. Tente usar o depurador de números para modificar os valores nas chamadas de função.

Interação com o usuário

Podemos girar o cubo com chamadas de função, mas é muito mais útil (e satisfatório) se permitirmos que o observador gire o cubo utilizando o mouse. Para isto, precisamos criar uma função mouseDragged(). Essa função é chamada automaticamente quando o usuário move o mouse com o botão pressionado.
mouseDragged = function() {
   rotateY3D(mouseX - pmouseX);
   rotateX3D(mouseY - pmouseY);
};
mouseX e mouseY são variáveis nativas que contêm a posição atual do mouse. pmouseX e pmouseY são variáveis nativas que contêm a posição do mouse no quadro anterior. Então, se a coordenada x aumentou (isto é, movemos o mouse para a direita), nós enviamos um valor positivo para rotateY3D() e giramos o cubo em torno do eixo y no sentido anti-horário.
Abaixo, você pode ver isso com seus próprios olhos.

Quer participar da conversa?

Nenhuma postagem por enquanto.
Você entende inglês? Clique aqui para ver mais debates na versão em inglês do site da Khan Academy.