Processing/JS

Random

processing emplea los números aleatorios para generar formas.

random(), randomGaussian (), randomSeed(), noise(), noiseSeed()

Muchos artiatas usan efectos aleatorios como una fuerza externa. El caos puede se canalizado para generar imágenes. Imágenes que mantienen una tensión entre orden y caos para llamar la atención.

Valores aleatórios

La funcción random() se usa para crear valores aleatorios en un rango que se especifica en sus parámetros.

random(high)
random(low, high)

En el ejemplo: random(5.0) devuelve valores entre 0.0 y 5.0. Si escribimos dos parámetros: random(-5.0, 10.2) devuelve valores entre -5.0 y 10.2.

Los números que devuelve random() son siempre decimales, no es possible asignarlos como  int. La función int() puede ser usado para converter el valor en int.

float f = random(5.2); // Asigna a f un valor float entre 0 y 5.2
int j = int(random(5.2)); // Asigna a j un valor int entre 0 y 5

Como los valores random no son predecibles, cada vez que se ejecuta el programa el resultado es diferente. En el ejemplo siguiente dibujamos lineas con las coordenadas y aleatorias.

smooth();
strokeWeight(10);
stroke(0, 130);
line(0, random(100), 100, random(100));
line(0, random(100), 100, random(100));
line(0, random(100), 100, random(100));
line(0, random(100), 100, random(100));
line(0, random(100), 100, random(100));

La posibilidad de usar en el random() dos parámetros posibilita un mayor control en los resultados. Si almacenamos el valor aleatorio en una variable, puede usarse para utilizar ese valor en mas de una ocasión en el programa.

En el siguiente ejemplo usamos la variable r a la que asignamos el valor aleatorio para que se use como coordenada y de la línea y el valor de su grosor.

smooth();
strokeWeight(20);
stroke(0, 230);
float r = random(5, 45);
stroke(r * 5.6, 230);
line(0, r, 100, random(55, 95));
r = random(5, 45);
stroke(r * 5.6, 230);
line(0, r, 100, random(55, 95));
r = random(5, 45);
stroke(r * 5.6, 230);
line(0, r, 100, random(55, 95));

Usar random() con una estructura for es la manera mas sencilla de generar números aleatorios.

background(0);
stroke(255, 60);
for (int i = 0; i < 100; i++) {
float r = random(10);
strokeWeight(r);
float offset = r * 5.0;
line(i-20, 100, i+offset, 0);
}

Usar valores aleatorios y un condicional para controlar el flujo del programa. En el primer ejemplo se dibujará una línea o una elipse según sea el valor mayor igual o menor de 50.

float r = random(100);
if (r < 50.0) {
line(0, 0, 100, 100);
} else {
ellipse(50, 50, 75, 75);
}

En el segundo ejemplo  se dibujaran entre 1 y 50 líneas verticales según el valor del random().

int num = int(random(50)) + 1;
for (int i = 0; i < num; i++) {
line(i * 2, 0, i * 2, 100);
}

En ocasiones es deseable tener números aleatorios pero que estén forzados según una secuencia. La función randomSeed() es la llave para producir tales numeros.

randomSeed(value)

El parámetro value debe ser un int. es la semilla de los valores que genera. Usando el mismo parámetro value en un programa cada vez que se ejecuta, se fuerza a producir el mismo número en el mismo orden.

En el siguiente ejemplo cambiamos el valor s asignado al randomSeed() de 6 a 12 para cambiar la imagen generada por el programa.

int s = 6; // Valor de la velocidead
background(0);
stroke(255, 60);
randomSeed(s); // Produce los mismos números cada vez
for (int i = 0; i < 100; i++) {
float r = random(10);
strokeWeight(r);
float offset = r * 5;
line(i-20, 100, i+offset, 0);
}

Con randomGaussian() el valor que obtenemos se ajusta a los valores de la campana de gauss

for (int y = 0; y < 100; y++) {
float x = randomGaussian() * 15;
line(y, height, y, 50 + x);
}

NOTA: Compara el resultado con valores random, randomSeed y randomGaussian.

Ruido

La function noise() se utiliza para generar valores aleatorios de una manera mas controlable.

Se usa la técnica desarrollada por Ken Perlin, usada para simular texturas naturales a través de pequeñas irregularidades. El ruido de Perlin se usa para generar superficies realistas en movimiento. Funciona interpolando entre valores aleatorios, creando transiciones suaves. El valor resultante será siempre entre 0.0 y 1.0. La función puede tener entre 1 a 3 parámetros que corresponden a 1D, 2D y 3D de ruido..

noise(x)
noise(x, y)
noise(x, y, z)

Un parámetro para generar un secuencia, dos valores para generar ruido en dos dimensiones y la versión de tres parámetros para generar texturas en tres dimensiones o texturas animadas en dos dimensiones.

La función noiseSeed() funciona de manera similar a randomSeed(), se usa para produce la misma secuencia de números cada vez que se ejecute el programa. En el siguiente ejemplo usamos la variable inc para definir la diferencia entre cada número.

inc = 0.01

inc = 0.1

size(600, 100);
float v = 0.0;
float inc = 0.1;
noStroke();
fill(0);
noiseSeed(0);
for (int i = 0; i < width; i = i+4) {
float n = noise(v) * 70.0;
rect(i, 10 + n, 3, 20);
v = v + inc;
}

Añadiendo un Segundo parámetro al ruido noise() generamos una textura en dos dimensiones. El tono de gris se genera con el segundo valor del ruido.

float xnoise = 0.0;
float ynoise = 0.0;
float inc = 0.1;
void draw () {
frameRate(12);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float gray = noise(xnoise, ynoise) * 255;
stroke(gray);
point(x, y);
xnoise = xnoise + inc;
}
xnoise = 0;
ynoise = ynoise + inc;
}
}

Podemos crear texturas usando noise() y sin().

float power = 3;
float d = 8;
noStroke();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float total = 0.0;
for (float i = d; i >= 1; i = i/2.0) {
total += noise(x/d, y/d) * d;
}
float turbulence = 128.0 * total / d;
float base = (x * 0.2) + (y * 0.12);
float offset = base + (power * turbulence / 256.0);
float gray = abs(sin(offset)) * 256.0;
stroke(gray);
point(x, y);
}
}