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?