Processing/JS

Trigonometría

En processing se emplea la trigonometría para generar formas.

https://www.processing.org/tutorials/trig/

PI, QUARTER_PI, HALF_PI, TWO_PI, radians(), degrees()
sin(), cos(), arc()

La trigonometría define las relaciones entre los lados y los ángulos de los triángulos. Las funciones trigonométricas como el seno y el coseno, generan números que pueden ser usados para generar ondas, círculos, arcos y espirales.

Los grados es la forma más común de medir los ángulos, un ángulo recto mide 90º, la mitad de un círculo son 180º y el círculo completo son 360º. En Processing y en programación en general los ángulos se miden en radianes. En radianes un ángulo recto mide π/2 radianes, la mitad del círculo es π radianes, y un círculo completo es 2π radianes.

El valor de π en processing se emplean 8 dígitos (3.1415927). La constante PI representa ese número, otras constantes que podemos usar son, QUARTER_PI, HALF_PI, y TWO_PI.

println(PI); // Escribe en la consola el valor de PI

Los ángulos pueden escribirse usando radians() o usando degrees().

Conversión entre ángulo de radianes a grados:

float r1 = radians(90);
float r2 = radians(180);
println(r1); // Escribe en la consola "1.5707964"
println(r2); // Escribe en la consola "3.1415927"
float d1 = degrees(PI);
float d2 = degrees(TWO_PI);
println(d1); // Escribe en la consola "180.0"
println(d2); // Escribe en la consola "360.0"

El ángulo de las funciones seno y coseno debe especificarse en radianes. Seno y coseno siempre devuelven un valor entre -1.0 y 1.0.

sin(angle)
cos(angle)

for (float angle = 0; angle < TWO_PI; angle += PI/24.0) {
println(sin(angle));
}

Los valores de sin() son números entre -1.0 y 1.0, son valores fáciles de usar, si se multiplican por 50 el valor que devuelve esta entre -50.0 y 50.0.

for (float angle = 0; angle < TWO_PI; angle += PI/24.0) {
println(sin(angle) * 50.0);
}

Para tener valores positivos, basta con sumar 1.0 y los valores estarán entre 0.0 y 2.0. Si este número lo divides por 2.0 el número resultante estará entre 0.0 y 1.0.

La function map() puede convertir los valores del sin() dentro de un rangor. En este ejemplo map() coloca los valores entre 0 y 1000.

for (float angle = 0; angle < TWO_PI; angle += PI/24.0) {
float newValue = map(sin(angle), -1, 1, 0, 1000);
println(newValue);
}

Si el valor del ángulo se va incrementando, la function sin() genera una onda.

size(700, 100);
noStroke();
fill(0);
float angle = 0.0;
for (int x = 0; x <= width; x += 5) {
float y = 50 + (sin(angle) * 35.0);
rect(x, y, 2, 4);
angle += PI/40.0;
}

Si variamos el incremento del ángulo, de PI/40.0 a PI/90.0 o PI/12.0, la onda resultante será diferente.

En este ejemplo modificamos la variable angleInc para modificar las dimensiones de la  onda.

size(700, 100);
noStroke();
smooth();
fill(0);
float offset = 50.0;
float scaleVal = 35.0; // Valor de la magnitud de la onda
float angleInc = PI/28.0; // Incremento entre el próximo ángulo
float angle = 0.0; // Ángulo que recibe los valores del seno
for (int x = 0; x <= width; x += 5) {
float y = offset + (sin(angle) * scaleVal);
rect(x, y, 2, 4);
angle += angleInc;
}

La función cos() función devuelve valores del mismo rango que sin(),

size(700, 100);
noStroke();
smooth();
float offset = 50.0;
float scaleVal = 20.0;
float angleInc = PI/18.0;
float angle = 0.0;
for (int x = 0; x <= width; x += 5) {
float y = offset + (sin(angle) * scaleVal);
fill(255);
rect(x, y, 2, 4);
y = offset + (cos(angle) * scaleVal);
fill(0);
rect(x, y, 2, 4);
angle += angleInc;
}

Ejemplos de uso de las funciones sin() para generar superficies.

size(700, 100);
float offset = 50;
float scaleVal = 30.0;
float angleInc = PI/56.0;
float angle = 0.0;
beginShape(TRIANGLE_STRIP);
for (int x = 4 ; x <= width+5; x += 5) {
float y = sin(angle) * scaleVal;
if ((x % 2) == 0) { // Every other time through the loop
vertex(x, offset + y);
} else {
vertex(x, offset - y);
}
angle += angleInc;
}
endShape();

size(700, 100);
smooth();
strokeWeight(2);
float offset = 126.0;
float scaleVal = 126.0;
float angleInc = 0.42;
float angle = 0.0;
for (int x = -52; x <= width; x += 5) {
float y = offset + (sin(angle) * scaleVal);
stroke(y);
line(x, 0, x+50, height);
angle += angleInc;
}

size(700, 100);
smooth();
fill(255, 20);
float scaleVal = 18.0;
float angleInc = PI/28.0;
float angle = 0.0;
for (int offset = -10; offset < width+10; offset += 5) {
for (int y = 0; y <= height; y += 2) {
float x = offset + (sin(angle) * scaleVal);
noStroke();
ellipse(x, y, 10, 10);
stroke(0);
point(x, y);
angle += angleInc;
}
angle += PI;
}

Circles, Arcs, Spirals

Con las funciones de seno y coseno, pueden dibujarse círculos.

En el siguiente ejemplo usaremos vamos incrementando el ángulo 12º hasta completar los 360º, en cada paso usaremos el coseno para calcular la coordenada x y el seno para calcular la coordenada y. Los valores seno y coseno devuelven valores entre -1.0 y 1.0, multiplicaremos el resultado por la variable radius (radio) 90 y añadimos100 a la x y la y para situar el centro en la posición (100, 100)

noStroke();
smooth();
size(200, 200);
int radius = 90;
for (int deg = 0; deg < 360; deg += 12) {
float angle = radians(deg);
float x = 100 + (cos(angle) * radius);
float y = 100 + (sin(angle) * radius);
ellipse(x, y, 6, 6);
}

Para dibujar arcos, Processing incluye la function arc():

arc(x, y, width, height, start, stop)

Un arco se dibuja sobre una elipse que definimos con los parámetros x, y, width, y height.

Los parámetros de comienzo del arco, start y el final, stop especifican los ángulos en radianes.

strokeWeight(2);
arc(50, 55, 50, 50, 0, HALF_PI);
arc(50, 55, 60, 60, HALF_PI, PI);
arc(50, 55, 70, 70, PI, TWO_PI - HALF_PI);
noFill();
arc(50, 55, 80, 80, TWO_PI - HALF_PI, TWO_PI);

Para dibujar una espiral, debemos multiplicar el seno y el coseno para que crezca o decrezca.

noStroke();
smooth();
float radius = 1.0;
for (int deg = 0; deg < 360*6; deg += 11) {
float angle = radians(deg);
float x = 75 + (cos(angle) * radius);
float y = 42 + (sin(angle) * radius);
ellipse(x, y, 6, 6);
radius = radius + 0.34;
}