¿Te acuerdas de todo esto?
ubicación = ubicación + velocidad
velocidad = velocidad + aceleración
¿Las cosas a las que nos dedicamos casi la totalidad de las dos últimas secciones? Bueno, podemos aplicar exactamente la misma lógica a un objeto que rota.
ángulo = ángulo + velocidad angular
velocidad angular = velocidad angular + aceleración angular
De hecho, lo anterior es en realidad más simple que con lo que empezamos porque un ángulo es una cantidad escalar: un solo número, ¡no un vector!
Usando la respuesta del desafío anterior, digamos que queremos rotar un bastón en ProcessingJS por un cierto ángulo. Escribiríamos un código como este:
translate(width/2, height/2);
rotate(angle);
line(-50, 0, 50, 0);
ellipse(50, 0, 8, 8);
ellipse(-50, 0, 8, 8);
Después de añadirle nuestros principios de movimiento, tenemos el siguiente programa. El bastón inicia en la pantalla sin rotación y luego gira más y más rápido a medida que el ángulo de rotación acelera:
Esta idea puede ser incorporada en nuestro objeto Mover. Por ejemplo, podemos agregar las propiedades relacionadas con movimiento angular a nuestro constructor Mover.

var Mover = function(m, x, y) {
    this.position = new PVector(x, y);
    this.mass = m;

    this.angle = 0;
    this.aVelocity = 0;
    this.aAcceleration = 0;

    this.velocity = new PVector(random(-1, 1), random(-1, 1));
    this.acceleration = new PVector(0, 0);
};
Y luego en update(), ¡actualizamos tanto la posición como el ángulo de acuerdo con el mismo algoritmo!
Mover.prototype.update = function () {

    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);

    this.aVelocity += this.aAcceleration;
    this.angle += this.aVelocity;

    this.acceleration.mult(0);
};
Por supuesto, para que cualquiera de estas cosas importen, también necesitamos rotar el objeto mientras lo desplegamos.
Mover.prototype.display = function () {
    stroke(0, 0, 0);
    fill(175, 175, 175, 200);
    rectMode(CENTER);

    // pushMatrix y popMatrix se necesitan para que la rotación
    // de la figura no afecte al resto del mundo
    pushMatrix();
    // Definir el origen de la ubicación de la figura
    translate(this.location.x, this.location.y);
    // Rotar por el ángulo
    rotate(this.angle);
    rect(0, 0, this.mass*16, this.mass*16);
    popMatrix();
};
Ahora, si en realidad ejecutáramos el código anterior, no veríamos nada nuevo. Esto es porque la aceleración angular (this.aAcceleration = 0;) está inicializada como cero. Para que el objeto rote, ¡necesitamos darle una aceleración! Ciertamente, podríamos incrustar en el código un número diferente:
this.aAcceleration = 0.01;
Aquí está cómo se vería un programa con la lógica anterior, con una fuerza calculada con base en un atractor central:
Eso es un buen comienzo, pero podemos producir un resultado más interesante asignando dinámicamente una aceleración angular según las fuerzas en el entorno: ¡ya que los objetos no suelen girar por su propia voluntad! Ahora, podemos ir bastante lejos por este camino, tratando de modelar la física de la aceleración angular utilizando los conceptos de torque y momento de inercia. Ese nivel de simulación está fuera del alcance de este curso, pero aún nos complicaremos un poco más.
Por el momento, una solución rápida y sucia será suficiente. Podemos producir resultados razonables simplemente calculando la aceleración angular como una función del vector de aceleración del objeto. Aquí está un ejemplo:
this.aAcceleration = this.acceleration.x;
Sí, esto es completamente arbitrario. Pero sí hace algo. Si el objeto se acelera hacia la derecha, su rotación angular acelera en sentido de las manecillas el reloj; una aceleración a la izquierda resulta en una rotación en contra de las manecillas del reloj. Por supuesto, es importante pensar acerca de la escala en este caso. La componente x del vector de aceleración puede ser una cantidad demasiado grande, causando que el objeto gire de una forma que parezca ridícula o poco realista. Así que dividir la componente x entre algún valor, o tal vez restringir la velocidad angular a un rango razonable, podría ser de mucha ayuda. Aquí está todo el método update() con estos ajustes añadidos.
Mover.prototype.update = function () {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);

    // Calcular la aceleración angular con base en la aceleración horizontal,
    // y dividir para que no sea tan fuerte
    this.aAcceleration = this.acceleration.x / 10.0;
    this.aVelocity += this.aAcceleration;

    // Usar restricción para garantizar que la velocidad
    // no lo haga girar fuera de control
    this.aVelocity = constrain(this.aVelocity, -0.1, 0.1);
    this.angle += this.aVelocity;

    this.acceleration.mult(0);
};
Aquí está cómo se ve el programa, con esos cambios incorporados:

Este curso de "Simulaciones Naturales" es un derivado de "La Naturaleza del Código" por Daniel Shiffman, usado bajo una Licencia Creative Commons Reconocimiento-NoComercial 3.0 Unported.