Rotar cosas en tres dimensiones suena complicado y puede serlo, pero hay algunas rotaciones sencillas. Por ejemplo, si nos imaginamos que rotamos nuestro cubo alrededor del eje z (que apunta para afuera de la pantalla), en realidad solo estamos rotando un cuadrado en dos dimensiones:

Una razón para aprender trigonometría

Diagrama de un triángulo
Podemos simplificar las cosas aún más, simplemente al mirar un solo nodo en la posición (x, 0). Utilizando trigonometría sencilla, podemos encontrar que la posición del punto después de rotarlo por θ alrededor del origen es:
x=x×cos(θ) x' = x \times cos(\theta)
y=x×sin(θ) y' = x \times sin(\theta)
Si no entiendes de dónde vienen estas ecuaciones, este video podría ayudar.

Rotar un punto alrededor del origen

Diagrama de un triángulo
El ejemplo anterior nos permite rotar un punto que empieza en el eje x alrededor del origen, ¿pero qué pasa si no está en el eje x? Esto requiere trigonometría ligeramente más avanzada. Si llamamos a la distancia entre el punto (x, y) y el origen r r y al ángulo entre la recta a (x, y) y el eje x α α , entonces:
Si rotamos por β al punto (x ', y '), entonces:
Utilizando algunas identidades trigonométricas, obtenemos:
Sustituyendo los valores de x y y de arriba, obtenemos una ecuación para las nuevas coordenadas como una función de las coordenadas originales y del ángulo de rotación:

Escribir una función de rotación

Ahora que sabemos las matemáticas, podemos escribir una función para rotar un nodo, o mejor aún, nuestro arreglo de nodos, alrededor del eje z. Esta función va a iterar sobre todos los nodos en el arreglo de nodos, encontrará sus coordenadas x y y actuales y luego las actualizará. Almacenamos sin(theta) y cos(theta) fuera del bucle para que solo tengamos que calcularlos una 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 rotar el cubo 30 grados, llamaremos a la función así:
rotateZ3D(30);
Puedes ver el cubo rotado a continuación. Es un poco más interesante que antes, pero no mucho:

Rotar en tres dimensiones

Ahora podemos rotar nuestro cubo en dos dimensiones, pero todavía parece un cuadrado. ¿Qué pasa si queremos rotar nuestro cubo alrededor del eje y (el eje vertical)? Si nos imaginamos que vemos nuestro cubo desde arriba a medida que lo rotamos alrededor del eje y, lo que veríamos sería un cuadrado que rota, igual que como cuando lo rotamos alrededor del eje z.
Podemos tomar la trigonometría y la función de antes y solo volver a etiquetar el eje para que el eje z se convierta en el eje y. En este caso, las coordenadas y del nodo no cambian, solo la x y la 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;
   }
};
Y podemos usar el mismo argumento para crear una función que rote nuestro cubo alrededor del eje 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;
   }
};
Ahora que tenemos esas funciones definidas, podemos rotar 30 grados alrededor de los otros dos ejes:
rotateX3D(30);
rotateY3D(30);
Puedes ver el código completo a continuación. Prueba utilizar el arrastra-números para cambiar los valores en las llamadas a las funciones.

Interacción del usuario

Podemos rotar el cubo agregando llamadas a funciones, pero es mucho más útil (y satisfactorio) si podemos habilitar que el espectador rote el cubo usando su ratón. Para esto necesitamos crear una función mouseDragged(). Esta función se llama automáticamente cuando se arrastra el ratón.
mouseDragged = function() {
   rotateY3D(mouseX - pmouseX);
   rotateX3D(mouseY - pmouseY);
};
mouseX y mouseY son variables incorporadas al sistema que contienen la posición actual del ratón. pmouseX y pmouseY son variables incorporadas al sistema que contienen la posición del ratón en el cuadro anterior de la animación. Así que si la coordenada x aumentó (movemos el ratón hacia la derecha), enviamos un valor positivo a rotateY3D() y rotamos el cubo alrededor del eje y en sentido contrario a las manecillas del reloj.
Puedes verlo por ti mismo a continuación.
Cargando