¿Ya estás sorprendido? En la sección de movimiento angular vimos algunos usos sorprendentes de la tangente (para encontrar el ángulo de un vector) y del seno y coseno (para convertir de coordenadas polares a cartesianas). Podríamos detenernos aquí y quedar satisfechos. Pero no lo vamos a hacer. Esto es solo el comienzo. Lo que el seno y coseno pueden hacer por ti va más allá de fórmulas matemáticas y triángulos rectángulos.
Veamos una gráfica de la función seno, donde y = seno(x)
Te darás cuenta que la salida de la función seno es una curva suave que alterna entre –1 y 1. Este tipo de comportamiento se conoce como oscilación, un movimiento periódico entre dos puntos. Tocar una cuerda de guitarra, el movimiento de un péndulo y rebotar en un brincolín son todos ejemplos de movimiento oscilatorio.
Y así felizmente descubrimos que podemos simular la oscilación en un programa de ProcessingJS al asignar la salida de la función seno a la ubicación de un objeto. Ten en cuenta que esta seguirá la misma metodología que aplicamos al ruido Perlin en la sección de ruido.
Vamos a empezar con un escenario muy básico. Queremos que un círculo oscile desde el lado izquierdo al lado derecho de la pantalla.
Esto es lo que se conoce como movimiento armónico simple (o, para ser más elegante, “la oscilación periódica sinusoidal de un objeto”). Va a ser un programa fácil de escribir, pero antes de meternos en el código, vamos a familiarizarnos con parte de la terminología de la oscilación (y las ondas).
El movimiento armónico simple se puede expresar como cualquier ubicación (en nuestro caso, la ubicación x) como una función del tiempo, con los dos elementos siguientes:
  • Amplitud: la distancia desde el centro del movimiento a cualquier extremo
  • Periodo: la cantidad de tiempo que tarda un ciclo completo de movimiento
Al mirar la gráfica del seno incrustada anteriormente, podemos ver que la amplitud es 1 y el periodo es de TWO_PI; la salida del seno nunca se eleva por encima de 1 o por debajo de -1; y cada TWO_PI radianes (o 360 grados) se repite el patrón de la onda.
Ahora, en el mundo de ProcessingJS en el que vivimos, ¿qué es amplitud y qué es periodo? La amplitud puede medirse fácilmente en pixeles. En el caso de una ventana de 200 pixeles de ancho, oscilaríamos desde el centro hasta 100 pixeles a la derecha y 100 pixeles a la izquierda. Por lo tanto:
// Nuestra amplitud medida en pixeles
var amplitude = 100;
El periodo es la cantidad de tiempo que tarda un ciclo, pero ¿qué es el tiempo en nuestro mundo de ProcessingJS? Es decir, sin duda podríamos decir que queremos que el círculo oscile cada tres segundos. Y podríamos llevar un registro de los milisegundos transcurridos en nuestro programa (usando millis()) e idear un algoritmo elaborado para hacer oscilar un objeto según el tiempo del mundo real.
Sin embargo, tenemos otra opción: podemos utilizar el hecho de que los programas de ProcessingJS tienen una noción de "cuadros" y que, de forma predeterminada, el programa intenta ejecutar 30 "cuadros por segundo". ProcessingJS nos da la variable frameCount para averiguar en qué cuadro estamos actualmente y la función frameRate() para cambiar la preferencia de cuadros por segundo. 30 CPS (cuadros por segundo o FPS, frames per second, en inglés) es la velocidad predeterminada de los cuadros, pues esa es una buena velocidad para producir una animación suave para engañar al cerebro humano, pero a veces puede ser útil hacer más lenta la velocidad de los cuadros, como cuando depuramos.
Así, podemos decidir basar nuestro periodo en el número de cuadros transcurridos que, como hemos visto, está estrechamente relacionado con el tiempo del mundo real. Podemos decir que el movimiento oscilatorio debe repetirse cada 30 cuadros, o 50 cuadros o 1000 cuadros, etc.
// Nuestro periodo medido en cuadros (nuestra unidad de tiempo para la animación)
var period = 120;
Una vez que tenemos la amplitud y el periodo, es tiempo de escribir una fórmula para calcular x como una función del tiempo, la cual sustituiremos por el conteo actual de los cuadros.
var x = amplitude * sin(TWO_PI * frameCount / period);
Vamos a analizar la fórmula un poco más y a tratar de entender cada componente. El primero es probablemente el más fácil. Lo que sea que salga de la función seno lo multiplicamos por la amplitud. Sabemos que el seno oscilará entre -1 y 1. Si tomamos ese valor y lo multiplicarmos por la amplitud obtendremos el resultado deseado: un valor que oscila entre -amplitud y amplitud. (Nota: este también es un lugar donde podemos usar la función map() de ProcessingJS para mapear la salida del seno a un rango personalizado).
Ahora, veamos lo que está dentro de la función seno:
TWO_PI * frameCount / period
¿Qué está pasando aquí? Vamos a empezar con lo que sabemos. Sabemos que el seno se repetirá cada 2*PI radianes. Es decir, comenzará en 0 y se repetirá en 2*PI, 4*PI, 6*PI, etc. Si el periodo es de 120 cuadros, entonces queremos que el movimiento oscilantorio se repita cuando el frameCount sea 120 cuadros, 240 cuadros, 360 cuadros, etc. frameCount es en realidad la única variable; empieza en 0 y cuenta hacia arriba. Veamos qué da la fórmula con esos valores.
frameCountframeCount / periodTWO_PI * frameCount / period
000
600.5PI
1201TWO_PI
24022 * TWO_PI (o 4* PI)
etc.  
frameCount dividido entre el periodo nos dice cuántos ciclos hemos completado. ¿Estamos a la mitad del primer ciclo? ¿Ya completamos dos ciclos? Al multiplicar ese número por TWO_PI, obtenemos el resultado que queremos, ya que TWO_PI es el número de radianes requeridos para que el seno complete un ciclo.
Para concluir, este es el programa que hace oscilar la ubicación x de un círculo con una amplitud de 100 pixeles y un periodo de 120 cuadros.
También vale la pena mencionar el término frecuencia: el número de ciclos por unidad de tiempo. La frecuencia es igual a 1 dividido entre el periodo. Si el periodo es de 120 cuadros, entonces solamente 1/120 de un ciclo se completa en un cuadro y así la frecuencia = 1/120 ciclos/cuadro. En el ejemplo anterior, simplemente elegimos definir la velocidad de oscilación en términos del periodo y por lo tanto no necesitamos una variable para la frecuencia.
Ten en cuenta que trabajamos por todo eso usando la función seno (sin() en ProcessingJS), pero las mismas ideas se aplican al uso de la función coseno. El periodo es el mismo para ambos, y la principal diferencia solo es si la amplitud al principio empieza en 1 o en 0.

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.