Difference between revisions of "Main Page"
| Line 20: | Line 20: | ||
DAISY WORLD | DAISY WORLD | ||
| + | ---- | ||
| + | |||
| + | |||
| + | // DAISYWORLD - Versione 100% VANILLA (nessuna libreria esterna!) | ||
| + | // Processing 4/5 - copia e incolla direttamente | ||
| + | |||
| + | int celle = 80; | ||
| + | float cellSize; | ||
| + | |||
| + | int[][] tipo; // 0 = suolo nudo, 1 = margherita bianca, 2 = margherita nera | ||
| + | float[][] temperatura; | ||
| + | |||
| + | // ---------- PARAMETRI MODIFICABILI CON TASTIERA E MOUSE ---------- | ||
| + | float albedoBianche = 0.75; | ||
| + | float albedoNere = 0.25; | ||
| + | float albedoSuolo = 0.50; | ||
| + | |||
| + | float luminositaSole = 1.00; // premi + e - per cambiare | ||
| + | float tassoCrescita = 0.40; // premi Q e A | ||
| + | float tempIdeale = 22.5; // premi W e S | ||
| + | float morteNaturale = 0.30; // premi E e D | ||
| + | |||
| + | void setup() { | ||
| + | size(800, 600); | ||
| + | cellSize = width / float(celle); | ||
| + | |||
| + | tipo = new int[celle][celle]; | ||
| + | temperatura = new float[celle][celle]; | ||
| + | |||
| + | // Poche margherite iniziali | ||
| + | randomSeed(123); // per risultati riproducibili | ||
| + | for (int x = 0; x < celle; x++) { | ||
| + | for (int y = 0; y < celle; y++) { | ||
| + | if (random(1) < 0.06) { | ||
| + | tipo[x][y] = random(1) < 0.5 ? 1 : 2; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void draw() { | ||
| + | background(40); | ||
| + | |||
| + | aggiornaTutto(); | ||
| + | |||
| + | // DISEGNA LA GRIGLIA | ||
| + | noStroke(); | ||
| + | for (int x = 0; x < celle; x++) { | ||
| + | for (int y = 0; y < celle; y++) { | ||
| + | if (tipo[x][y] == 1) fill(255); // bianca | ||
| + | else if (tipo[x][y] == 2) fill(20); // nera | ||
| + | else fill(139, 105, 60); // suolo marrone | ||
| + | rect(x*cellSize, y*cellSize, cellSize, cellSize); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // INFO A SCHERMO | ||
| + | fill(255); | ||
| + | textSize(16); | ||
| + | textAlign(LEFT); | ||
| + | int y = 30; | ||
| + | text("Luminosità sole: " + nf(luminositaSole,1,2) + " [+] [-]", 15, y+=25); | ||
| + | text("Tasso crescita: " + nf(tassoCrescita,1,2) + " [Q] [A]", 15, y+=25); | ||
| + | text("Temp. ideale: " + nf(tempIdeale,1,1) + "°C [W] [S]", 15, y+=25); | ||
| + | text("Morte naturale: " + nf(morteNaturale,1,2) + " [E] [D]", 15, y+=30); | ||
| + | text("Temperatura media: " + nf(temperaturaMedia(),1,1) + "°C", 15, y+=30); | ||
| + | text("Bianche: " + conta(1) + " Nere: " + conta(2) + " Tot: " + (conta(1)+conta(2)), 15, y+=30); | ||
| + | text("Premi SPAZIO per ripartire da zero", 15, y+=30); | ||
| + | } | ||
| + | |||
| + | // ------------------------------------------------------------------ | ||
| + | void aggiornaTutto() { | ||
| + | // 1. Calcola albedo medio del pianeta | ||
| + | float albedoTot = 0; | ||
| + | for (int x=0; x<celle; x++) for (int y=0; y<celle; y++) { | ||
| + | if (tipo[x][y]==1) albedoTot += albedoBianche; | ||
| + | else if (tipo[x][y]==2) albedoTot += albedoNere; | ||
| + | else albedoTot += albedoSuolo; | ||
| + | } | ||
| + | float albedoMedio = albedoTot / (celle*celle); | ||
| + | |||
| + | // 2. Temperatura planetaria (modello molto semplificato) | ||
| + | float tempPlanetaria = luminositaSole * (1 - albedoMedio) * 80 + 5; | ||
| + | |||
| + | // 3. Temperatura locale di ogni cella | ||
| + | for (int x=0; x<celle; x++) for (int y=0; y<celle; y++) { | ||
| + | float a = (tipo[x][y]==1 ? albedoBianche : tipo[x][y]==2 ? albedoNere : albedoSuolo); | ||
| + | temperatura[x][y] = tempPlanetaria * (1 - a) * 1.4; // le nere si scaldano di più | ||
| + | } | ||
| + | |||
| + | // 4. Aggiorna popolazione (un passo alla volta) | ||
| + | int[][] nuovo = new int[celle][celle]; | ||
| + | for (int x=0; x<celle; x++) nuovo[x] = tipo[x].clone(); | ||
| + | |||
| + | for (int x=0; x<celle; x++) { | ||
| + | for (int y=0; y<celle; y++) { | ||
| + | |||
| + | // morte casuale | ||
| + | if (tipo[x][y] != 0 && random(1) < morteNaturale/100) { | ||
| + | nuovo[x][y] = 0; | ||
| + | continue; | ||
| + | } | ||
| + | |||
| + | // solo le celle vuote possono essere colonizzate | ||
| + | if (tipo[x][y] == 0) { | ||
| + | float t = temperatura[x][y]; | ||
| + | float crescita = tassoCrescita * (1.0 - sq((t - tempIdeale)/17)); | ||
| + | crescita = max(0, crescita); | ||
| + | |||
| + | // c'è almeno una margherita vicina? | ||
| + | boolean vicino = false; | ||
| + | for (int dx=-1; dx<=1 && !vicino; dx++) | ||
| + | for (int dy=-1; dy<=1 && !vicino; dy++) { | ||
| + | int nx = (x+dx+celle)%celle; | ||
| + | int ny = (y+dy+celle)%celle; | ||
| + | if (tipo[nx][ny] != 0) vicino = true; | ||
| + | } | ||
| + | |||
| + | if (vicino && random(1) < crescita) { | ||
| + | nuovo[x][y] = random(1)<0.5 ? 1 : 2; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | tipo = nuovo; | ||
| + | } | ||
| + | |||
| + | float temperaturaMedia() { | ||
| + | float somma = 0; | ||
| + | for (float[] riga : temperatura) for (float t : riga) somma += t; | ||
| + | return somma / (celle*celle); | ||
| + | } | ||
| + | |||
| + | int conta(int colore) { | ||
| + | int c = 0; | ||
| + | for (int[] riga : tipo) for (int cella : riga) if (cella == colore) c++; | ||
| + | return c; | ||
| + | } | ||
| + | |||
| + | // ------------------------------------------------------------------ | ||
| + | // COMANDI TASTIERA | ||
| + | void keyPressed() { | ||
| + | if (key == ' ') { // reset | ||
| + | for (int x=0; x<celle; x++) | ||
| + | for (int y=0; y<celle; y++) | ||
| + | tipo[x][y] = (random(1)<0.05) ? (random(1)<0.5?1:2) : 0; | ||
| + | } | ||
| + | |||
| + | // modifica parametri | ||
| + | if (key == '+' || keyCode == UP) luminositaSole = min(2.0, luminositaSole + 0.02); | ||
| + | if (key == '-' || keyCode == DOWN) luminositaSole = max(0.3, luminositaSole - 0.02); | ||
| + | |||
| + | if (key == 'q' || key == 'Q') tassoCrescita = min(1.0, tassoCrescita + 0.02); | ||
| + | if (key == 'a' || key == 'A') tassoCrescita = max(0.0, tassoCrescita - 0.02); | ||
| + | |||
| + | if (key == 'w' || key == 'W') tempIdeale = min(40, tempIdeale + 0.5); | ||
| + | if (key == 's' || key == 'S') tempIdeale = max(5, tempIdeale - 0.5); | ||
| + | |||
| + | if (key == 'e' || key == 'E') morteNaturale = min(2.0, morteNaturale + 0.05); | ||
| + | if (key == 'd' || key == 'D') morteNaturale = max(0.0, morteNaturale - 0.05); | ||
| + | } | ||
Revision as of 17:16, 21 November 2025
Welcome to my website!
I am a physicst. I work at the Department of Physics, University of Genoa.
INFN associate (INFN section of Genoa). Member of AIF and SIF, EPS and IEEE. Also member of [AI] Also active member of AISTAP and WCGTC.
An overview of my training and former positions can be found in brief biography and/or CV.
My main interests are in Research and Development, Didactics (Teachings) and the Societal impact of Research and Didactics.
Areas of interests are mainly (but not only): medical physics, imaging, statistics, data analysis, computational physics, physical computing, astrophysics, nuclear physics, robotics, vision, ML, AI
Information on my activities can be found here: projects, publications, teachings.
I live in continuous learning mode: here some usefull (to me) stuff: notes, howto, links, web links, lists and software sections.
DAISY WORLD
// DAISYWORLD - Versione 100% VANILLA (nessuna libreria esterna!)
// Processing 4/5 - copia e incolla direttamente
int celle = 80; float cellSize;
int[][] tipo; // 0 = suolo nudo, 1 = margherita bianca, 2 = margherita nera float[][] temperatura;
// ---------- PARAMETRI MODIFICABILI CON TASTIERA E MOUSE ---------- float albedoBianche = 0.75; float albedoNere = 0.25; float albedoSuolo = 0.50;
float luminositaSole = 1.00; // premi + e - per cambiare float tassoCrescita = 0.40; // premi Q e A float tempIdeale = 22.5; // premi W e S float morteNaturale = 0.30; // premi E e D
void setup() {
size(800, 600);
cellSize = width / float(celle);
tipo = new int[celle][celle];
temperatura = new float[celle][celle];
// Poche margherite iniziali
randomSeed(123); // per risultati riproducibili
for (int x = 0; x < celle; x++) {
for (int y = 0; y < celle; y++) {
if (random(1) < 0.06) {
tipo[x][y] = random(1) < 0.5 ? 1 : 2;
}
}
}
}
void draw() {
background(40);
aggiornaTutto();
// DISEGNA LA GRIGLIA
noStroke();
for (int x = 0; x < celle; x++) {
for (int y = 0; y < celle; y++) {
if (tipo[x][y] == 1) fill(255); // bianca
else if (tipo[x][y] == 2) fill(20); // nera
else fill(139, 105, 60); // suolo marrone
rect(x*cellSize, y*cellSize, cellSize, cellSize);
}
}
// INFO A SCHERMO
fill(255);
textSize(16);
textAlign(LEFT);
int y = 30;
text("Luminosità sole: " + nf(luminositaSole,1,2) + " [+] [-]", 15, y+=25);
text("Tasso crescita: " + nf(tassoCrescita,1,2) + " [Q] [A]", 15, y+=25);
text("Temp. ideale: " + nf(tempIdeale,1,1) + "°C [W] [S]", 15, y+=25);
text("Morte naturale: " + nf(morteNaturale,1,2) + " [E] [D]", 15, y+=30);
text("Temperatura media: " + nf(temperaturaMedia(),1,1) + "°C", 15, y+=30);
text("Bianche: " + conta(1) + " Nere: " + conta(2) + " Tot: " + (conta(1)+conta(2)), 15, y+=30);
text("Premi SPAZIO per ripartire da zero", 15, y+=30);
}
// ------------------------------------------------------------------ void aggiornaTutto() {
// 1. Calcola albedo medio del pianeta
float albedoTot = 0;
for (int x=0; x<celle; x++) for (int y=0; y<celle; y++) {
if (tipo[x][y]==1) albedoTot += albedoBianche;
else if (tipo[x][y]==2) albedoTot += albedoNere;
else albedoTot += albedoSuolo;
}
float albedoMedio = albedoTot / (celle*celle);
// 2. Temperatura planetaria (modello molto semplificato)
float tempPlanetaria = luminositaSole * (1 - albedoMedio) * 80 + 5;
// 3. Temperatura locale di ogni cella
for (int x=0; x<celle; x++) for (int y=0; y<celle; y++) {
float a = (tipo[x][y]==1 ? albedoBianche : tipo[x][y]==2 ? albedoNere : albedoSuolo);
temperatura[x][y] = tempPlanetaria * (1 - a) * 1.4; // le nere si scaldano di più
}
// 4. Aggiorna popolazione (un passo alla volta)
int[][] nuovo = new int[celle][celle];
for (int x=0; x<celle; x++) nuovo[x] = tipo[x].clone();
for (int x=0; x<celle; x++) {
for (int y=0; y<celle; y++) {
// morte casuale
if (tipo[x][y] != 0 && random(1) < morteNaturale/100) {
nuovo[x][y] = 0;
continue;
}
// solo le celle vuote possono essere colonizzate
if (tipo[x][y] == 0) {
float t = temperatura[x][y];
float crescita = tassoCrescita * (1.0 - sq((t - tempIdeale)/17));
crescita = max(0, crescita);
// c'è almeno una margherita vicina?
boolean vicino = false;
for (int dx=-1; dx<=1 && !vicino; dx++)
for (int dy=-1; dy<=1 && !vicino; dy++) {
int nx = (x+dx+celle)%celle;
int ny = (y+dy+celle)%celle;
if (tipo[nx][ny] != 0) vicino = true;
}
if (vicino && random(1) < crescita) {
nuovo[x][y] = random(1)<0.5 ? 1 : 2;
}
}
}
}
tipo = nuovo;
}
float temperaturaMedia() {
float somma = 0; for (float[] riga : temperatura) for (float t : riga) somma += t; return somma / (celle*celle);
}
int conta(int colore) {
int c = 0; for (int[] riga : tipo) for (int cella : riga) if (cella == colore) c++; return c;
}
// ------------------------------------------------------------------ // COMANDI TASTIERA void keyPressed() {
if (key == ' ') { // reset
for (int x=0; x<celle; x++)
for (int y=0; y<celle; y++)
tipo[x][y] = (random(1)<0.05) ? (random(1)<0.5?1:2) : 0;
}
// modifica parametri
if (key == '+' || keyCode == UP) luminositaSole = min(2.0, luminositaSole + 0.02);
if (key == '-' || keyCode == DOWN) luminositaSole = max(0.3, luminositaSole - 0.02);
if (key == 'q' || key == 'Q') tassoCrescita = min(1.0, tassoCrescita + 0.02);
if (key == 'a' || key == 'A') tassoCrescita = max(0.0, tassoCrescita - 0.02);
if (key == 'w' || key == 'W') tempIdeale = min(40, tempIdeale + 0.5);
if (key == 's' || key == 'S') tempIdeale = max(5, tempIdeale - 0.5);
if (key == 'e' || key == 'E') morteNaturale = min(2.0, morteNaturale + 0.05);
if (key == 'd' || key == 'D') morteNaturale = max(0.0, morteNaturale - 0.05);
}
GAME OF LIFE
// CONWAY'S GAME OF LIFE - Stessa identica logica del Daisyworld // Nessuna libreria esterna - copia e incolla e funziona subito!
int celle = 80; float cellSize;
int[][] griglia; // 0 = morta, 1 = viva int[][] nuovaGriglia;
boolean pausa = false; // premi P per mettere in pausa/riprendere float velocita = 10; // frame al secondo (premi +/- per cambiare velocità)
void setup() {
size(800, 600);
cellSize = width / float(celle);
griglia = new int[celle][celle];
nuovaGriglia = new int[celle][celle];
// Configurazione casuale iniziale (30% di celle vive)
randomSeed(42);
for (int x = 0; x < celle; x++) {
for (int y = 0; y < celle; y++) {
griglia[x][y] = random(1) < 0.3 ? 1 : 0;
}
}
frameRate(velocita);
}
void draw() {
background(20);
if (!pausa) {
aggiornaGameOfLife();
}
// DISEGNA LA GRIGLIA
noStroke();
for (int x = 0; x < celle; x++) {
for (int y = 0; y < celle; y++) {
if (griglia[x][y] == 1) {
fill(0, 255, 100); // verde neon per celle vive
} else {
fill(40); // grigio scuro per morte
}
rect(x*cellSize, y*cellSize, cellSize, cellSize);
}
}
// Bordini leggeri per vedere meglio le celle
stroke(50);
noFill();
for (int x = 0; x <= celle; x++) {
line(x*cellSize, 0, x*cellSize, height);
}
for (int y = 0; y <= celle; y++) {
line(0, y*cellSize, width, y*cellSize);
}
noStroke();
// INFO A SCHERMO
fill(255);
textSize(16);
textAlign(LEFT);
int y = 30;
text("GAME OF LIFE", 15, y+=25);
text("Celle vive: " + contaVive(), 15, y+=30);
text("Generazione: " + frameCount, 15, y+=25);
text("Velocità: " + nf(velocita,1,1) + " fps [+] [-]", 15, y+=30);
text("Pausa: " + (pausa ? "SÌ [P]" : "NO [P]"), 15, y+=30);
text("R = casuale C = pulisci G = glider gun SPAZIO = reset casuale", 15, y+=35);
text("Clic sinistro = disegna Clic destro/tasto = cancella", 15, y+=25);
}
// ------------------------------------------------------------------ void aggiornaGameOfLife() {
// Regole classiche di Conway
for (int x = 0; x < celle; x++) {
for (int y = 0; y < celle; y++) {
int vicini = contaVicini(x, y);
if (griglia[x][y] == 1) {
// Sopravvive solo con 2 o 3 vicini
nuovaGriglia[x][y] = (vicini == 2 || vicini == 3) ? 1 : 0;
} else {
// Nasce solo con esattamente 3 vicini
nuovaGriglia[x][y] = (vicini == 3) ? 1 : 0;
}
}
}
// Scambia le griglie
int[][] temp = griglia;
griglia = nuovaGriglia;
nuovaGriglia = temp;
}
int contaVicini(int x, int y) {
int conta = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue;
int nx = (x + dx + celle) % celle;
int ny = (y + dy + celle) % celle;
if (griglia[nx][ny] == 1) conta++;
}
}
return conta;
}
int contaVive() {
int c = 0;
for (int x = 0; x < celle; x++)
for (int y = 0; y < celle; y++)
if (griglia[x][y] == 1) c++;
return c;
}
// ------------------------------------------------------------------ // COMANDI TASTIERA (uguali al Daisyworld!) void keyPressed() {
if (key == ' ') {
// Reset casuale
for (int x = 0; x < celle; x++)
for (int y = 0; y < celle; y++)
griglia[x][y] = random(1) < 0.3 ? 1 : 0;
}
if (key == 'r' || key == 'R') { // Random
for (int x = 0; x < celle; x++)
for (int y = 0; y < celle; y++)
griglia[x][y] = random(1) < 0.25 ? 1 : 0;
}
if (key == 'c' || key == 'C') { // Pulisci tutto
for (int x = 0; x < celle; x++)
for (int y = 0; y < celle; y++)
griglia[x][y] = 0;
}
if (key == 'g' || key == 'G') { // Glider Gun di Gosper!
pulisci();
gliderGun();
}
if (key == 'p' || key == 'P') {
pausa = !pausa;
}
if (key == '+' || key == '=') {
velocita = min(60, velocita + 2);
frameRate(velocita);
}
if (key == '-' || key == '_') {
velocita = max(1, velocita - 2);
frameRate(velocita);
}
}
// Disegno a mano con il mouse void mousePressed() {
int x = floor(mouseX / cellSize);
int y = floor(mouseY / cellSize);
if (x >= 0 && x < celle && y >= 0 && y < celle) {
if (mouseButton == LEFT) griglia[x][y] = 1;
if (mouseButton == RIGHT) griglia[x][y] = 0;
}
}
void mouseDragged() {
mousePressed(); // permette di disegnare tenendo premuto
}
// Configurazioni famose void gliderGun() {
// Gosper Glider Gun (funziona perfettamente!)
int[][] gun = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
pulisci();
for (int x = 0; x < gun.length; x++) {
for (int y = 0; y < gun[0].length; y++) {
if (x < celle && y < celle)
griglia[x+10][y+10] = gun[y][x]; // ruotato per entrare bene
}
}
}
void pulisci() {
for (int x = 0; x < celle; x++)
for (int y = 0; y < celle; y++)
griglia[x][y] = 0;
}
I am intereseted/involved in the following calls, projects, proposals (dashboard) with AISTAP, AIF.
You may contact me at the following address:
Daniele Grosso (Ph.D) LTD LAB (Low Temperature Detectors LAB) DIFI (Department of Physics, University of genoa) INFN (INFN section of Genoa) v. Dodecaneso 33, 16146 Genova (GE) - IT Tel. +39.347.496.5037 Skype: daniele.grosso.genova daniele.grosso@unige.it, daniele.grosso@ge.infn.it daniele.grosso.genova@gmail.com