Capitolo 3 - palline magiche
Fino a questo momento abbiamo simulato un universo con la sola legge del moto rettilineo uniforme. E' arrivato il momento di includere anche l'accelerazione nei nostri modelli!
Il nostro scopo è di simulare due oggetti che cadono verso il basso di moto accelerato uniforme, rimbalzando sulle pareti con urti perfettamente elastici.
Nella scheda Ball copiamo il codice seguente:
class Ball
{
////////////////////
// PROPRIETA'
////////////////////
float x, y, vx, vy, g; // posizione, velocità e accelerazione verticale
int dim; // raggio
color col; // colore
// costruttore 1: non ha parametri di ingresso, decide tutto internamente
Ball()
{
x = width/2;
y = height/2;
vx = random(-5, 5);
vy = random(-5, 5);
g = 0.1;
dim = (int)random(5, 60);
col = color(random(255), random(255), random(255));
}
// costruttore 2: ha due parametri di ingresso, x e y della posizione
Ball(float _x, float _y)
{
x = _x;
y = _y;
vx = random(-5, 5);
vy = random(-5, 5);
g = 0.1;
dim = (int)random(5, 30);
col = color(random(255), random(255), random(255));
}
Ball(float _x, float _y, float _vx, float _vy)
{
x = _x;
y = _y;
vx = _vx;
vy = _vy;
g = 0.1;
dim = (int)random(5, 30);
col = color(random(255), random(255), random(255));
}
////////////////////
// METODI
////////////////////
// metodo show: definisce la visualizzazione dell'oggetto
void show()
{
stroke(0);
strokeWeight(1);
fill(col);
ellipse(x, y, dim*2, dim*2);
}
// metodo update: definisce l'aggiornamento dello stato dell'oggetto
void update()
{
// gestione dei rimbalzi
if (x > width - dim) // se picchia contro la parete destra
{
x = width - dim; // fissa la posizione esattamente sul limite
vx = -vx; // inverti la componente orizzontale della velocità
}
if (x < dim)
{
x = dim;
vx = -vx;
}
if (y > height - dim)
{
y = height - dim;
vy = -vy;
}
if (y < dim)
{
y = dim;
vy = -vy;
}
vy += g; // aggiorna la velocità verticale
x += vx; // aggiorna la componente orizzontale della posizione
y += vy; // aggiorna la componente verticale della posizione
}
}
La classe è rimasta sostanzialmente la stessa, tranne per il fatto che abbiamo aggiornato la funzione update inserendo la gestione delle collisioni con le pareti e l'aggiornamento della velocità verticale.
Questo, invece, è il codice del programma che usa la classe:
Ball b1, b2;
void setup()
{
size(800, 600);
b1 = new Ball(width*5/50, height/20, 0, 0);
b2 = new Ball(width*45/50, height/20, -5, 0);
}
void draw()
{
background(255);
fill(0);
text("vx: " + b1.vx, 20, 20, 120, 80);
text("vy: " + b1.vy, 20, 40, 120, 80);
b1.update();
b1.show();
b2.update();
b2.show();
}
Questa volta gli oggetti creati sono due, ma il procedimento logico è perfettamente identico al caso di un solo oggetto.
Cosa dovrei fare per simulare un mondo dove le palline precipitano verso la parete destra invece che verso il pavimento?
E se volessi simulare la diminuzione di energia dovuta all'attrito con l'aria?