xxxxxxxxxx
228
let popolazione_max = 100;
let popolazione = 30;
let numero_cerchi = popolazione + 1;
let x = [numero_cerchi];
let y = [numero_cerchi];
let target_x = [numero_cerchi];
let target_y = [numero_cerchi];
let trigger = [numero_cerchi] , trigger_pre = [numero_cerchi];
let lunghezza_a = [numero_cerchi];
let lunghezza_b = [numero_cerchi];
let lunghezza_c = [numero_cerchi];
let semiperimetro = [numero_cerchi];
let area = [numero_cerchi];
let riempi_triangoli = [numero_cerchi];
let osc = [numero_cerchi - 2];
let modulante = [numero_cerchi - 2];
let frequenza = [numero_cerchi - 2];
let ampiezza = [numero_cerchi - 2];
let freq_min = 100;
let freq_max = 800;
let forma_onda = [numero_cerchi - 2];
//se l'area uno dei triangoli è maggiore del 50% dell'area di tutti i triangoli -> levo un triangolo
//se l'area uno dei triangoli è minore del 50% dell'area di tutti i triangoli -> aggiungo un triangolo
//oppure
//se la somma di tutte le aree supera il x% dell'area totale -> aggiungo un triangolo
//superata una soglia critica x% è molto più probabile che si eliminino molti triangoli
//https://en.wikipedia.org/wiki/Critical_transition
//se la somma di tutte le aree è minore del x% dell'area totale -> levo un triangolo
//il nuovo triangolo generato porta informazioni "genetiche" sul colore dei sui due triangoli precedenti
function setup() {
createCanvas(windowWidth, windowHeight);
raggio = width * 0.01;
frameRate(28);
for(let i = 0; i < numero_cerchi; i++) {
x[i] = 0;
y[i] = 0;
target_x[i] = floor(random(width));
target_y[i] = floor(random(height));
area[i] = 0;
trigger[i] = 0;
trigger_pre[i] = 0;
// riempi_triangoli[i] = ((i + 1) / numero_cerchi) * 255;
riempi_triangoli[i] = random(230);
if (i > 0){
while (abs(riempi_triangoli[i] - riempi_triangoli[i - 1]) < 25 || riempi_triangoli[i] == 50) {
riempi_triangoli[i] = random(230);
}
}
}
for (let i = 0; i < numero_cerchi - 2; i++) {
if (riempi_triangoli[i] <= 60) {
forma_onda[i] = 'sine';
}
else if (riempi_triangoli[i] > 60 && riempi_triangoli[i] <= 120 ) {
forma_onda[i] = 'triangle';
}
else if (riempi_triangoli[i] > 120 && riempi_triangoli[i] <= 180 ) {
forma_onda[i] = 'square';
}
else {
forma_onda[i] = 'sawtooth';
}
osc[i] = new p5.Oscillator('sine');
osc[i].start();
modulante[i] = new p5.Oscillator(forma_onda[i]);
modulante[i].start();
modulante[i].disconnect(); //disconnetto modulante da output
}
} //fine setup()
function draw() {
background(50);
stroke(255);
for (let i = 0; i < numero_cerchi; i++) {
if (x[i] < target_x[i]) {
x[i]++;
}
if (x[i] > target_x[i]) {
x[i]--;
}
if (x[i] == target_x[i]) {
target_x[i] = floor(random(width));
frequenza[i] = map(x[i], 0, width, freq_min, freq_max);
}
if (y[i] < target_y[i]) {
y[i]++;
}
if (y[i] > target_y[i]) {
y[i]--;
}
if (y[i] == target_y[i]) {
target_y[i] = floor(random(height));
frequenza[i] = map(y[i], 0, height, freq_min, freq_max);
}
} //fine for generazione grafica
//-------------calcolo triangoli----------------//
for (let i = 0; i < numero_cerchi; i++) {
fill(riempi_triangoli[i]);
if (i < (numero_cerchi - 2)) {
triangle(x[i], y[i], x[i +1], y[i + 1], x[i + 2], y[i + 2]);
lunghezza_a[i] = calcola_lunghezza(x[i], x[i + 1], y[i], y[i + 1]);
lunghezza_b[i] = calcola_lunghezza(x[i + 1], x[i + 2], y[i + 1], y[i + 2]);
lunghezza_c[i] = calcola_lunghezza(x[i + 2], x[i], y[i + 2], y[i]);
semiperimetro[i] = somma_lunghezze(lunghezza_a[i], lunghezza_b[i], lunghezza_c[i]);
area[i] = calcola_eulero(semiperimetro[i], lunghezza_a[i], lunghezza_b[i], lunghezza_c[i]);
}
else if (i < (numero_cerchi - 1)) {
triangle(x[i], y[i], x[i + 1], y[i + 1], x[numero_cerchi - 1], y[numero_cerchi - 1]);
lunghezza_a[i] = calcola_lunghezza(x[i], x[i + 1], y[i], y[i + 1]);
lunghezza_b[i] = calcola_lunghezza(x[i + 1], x[numero_cerchi - 1], y[i + 1], y[numero_cerchi - 1]);
lunghezza_c[i] = calcola_lunghezza(x[numero_cerchi - 1], x[i], y[numero_cerchi - 1], y[i]);
semiperimetro[i] = somma_lunghezze(lunghezza_a[i], lunghezza_b[i], lunghezza_c[i]);
area[i] = calcola_eulero(semiperimetro[i], lunghezza_a[i], lunghezza_b[i], lunghezza_c[i]);
}
}//fine calcolo triangoli
//-------------sintesi sonora----------------//
for (let i = 0; i < numero_cerchi - 2; i++) {
ampiezza[i] = map(area[i], 0, 80000, 0.0001, (1 / (numero_cerchi - 1)));
if (i < numero_cerchi - 3) {
//frequenza[i] = map(x[i], 0, width, freq_min, freq_max);
modulante[i].freq(frequenza[i + 1]);
modulante[i].amp(area[i + 1] * 0.2 * (y[i + 1] / height) + 1);
osc[i].freq(frequenza[i]);
osc[i].freq(modulante[i]);
osc[i].amp(ampiezza[i] + 0.00001);
}
else {
//frequenza[i] = map(x[i], 0, width, freq_min, freq_max);
modulante[i].freq(frequenza[0]);
modulante[i].amp(area[0] * 0.2 * (y[0] / height) + 1);
osc[i].freq(frequenza[i]);
osc[i].freq(modulante[i]);
osc[i].amp(ampiezza[i]);
}
} // fine sintesi sonora
//-------------utility----------------//
for (let i = 0; i < numero_cerchi; i++) {
trigger_pre[i] = trigger[i];
}
/* print(int(area[0] * 0.2 * (y[0] / height)),
int(area[1] * 0.2 * (y[1] / height)),
int(area[2] * 0.2 * (y[2] / height)),
int(area[3] * 0.2 * (y[3] / height))); */
} //fine draw()
function calcola_lunghezza(x1, x2, y1, y2) {
return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
function somma_lunghezze(L1, L2, L3) {
return ((L1 + L2 + L3) * 0.5);
}
function calcola_eulero(p, a, b, c) {
return sqrt(p * (p - a) * (p - b) * (p - c));
}