> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.WQKeeMxFXyu/rev.252
 * 
 * authors: 
 *   Andrea Paraggio
 *   

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/* @pjs preload="/static/uploaded_resources/p.469/map.png"; */

PImage mapImage = loadImage("/static/uploaded_resources/p.469/map.png");

Integrator[] interpolators;

float plotX1, plotY1, plotX2, plotY2;

float plotWidth, plotHeight;

float bloodMin, bloodMax;

float startWidth = 865.00;
float startHeight = 815.00;

int numOspedali;

String[] nomiOspedali = 
{ "CTO A. ALesini",
  "Fatebenefratelli Villa S. Pietro",
  "G.B. Grassi",
  "Ospedale Pediatrico Bambino Gesù",
  "Policlinico Casilino",
  "Policlinico Gemelli",
  "Policlinico Umberto I",
  "Policlinico Tor Vergata",
  "Ospedale Sandro Pertini",
  "San Camillo Forlanini",
  "Sant'Andrea",
  "Sant'Eugenio",
  "San Filippo Neri",
  "San Giovanni Addolorata",
  "San Giovanni Calibita Fatebenefratelli",
  "Ospedale Santo Spirito",
  "Ospedale Militare Celio",
  "IFO",
  "Campus Bio-medico"
};

float[] coordX =
{ 503.06,
  396.14,
  59.06,
  425.39,
  768.19,
  342.39,
  551.06,
  797.06,
  633.73,
  410.73,
  449.14,
  473.89,
  294.06,
  527.06,
  463.73,
  447.39,
  512.73,
  331.68,
  604.39
};

float[] coordY =
{ 498.56,
  131.56,
  782.89,
  356.89,
  447.44,
  238.23,
  332.23,
  484.89,
  264.23,
  477.23,
  61.39,
  622.89,
  195.56,
  396.89,
  379.89,
  351.56,
  411.23,
  794.28,
  792.89
};

float[] blood =
{ 44.0,
  34.2,
  18.2,
  4.5,
  67.4,
  53.4,
  9.6,
  23.6,
  30.0,
  11.9,
  59.5,
  34.5,
  81.3,
  61.2,
  41.4,
  38.4,
  16.2,
  18.1,
  29.2
};


void setup() {
  size(605,570);
  
  plotX1 = 50;
  plotX2 = width - plotX1;
  plotY1 = 50;
  plotY2 = height - plotY1;
  
  plotWidth = width-plotX1*2;
  plotHeight = height-plotY1*2;
  
  bloodMax = max(blood);
  bloodMin = min(blood);
  
  numOspedali = nomiOspedali.length;
  
  // Carica i valori all'interno dell'array interpolators
  interpolators = new Integrator[numOspedali];
  for(int i=0; i<numOspedali; i++) {
    float initialValue = blood[i];
    interpolators[i] = new Integrator(initialValue,0.9,0.1);
  }
  
  smooth();
  frameRate(30);
}


void draw() {
  background(#FFFFFF);
  
  // Disegno del plot
  fill(#FFFFFF);
  rectMode(CORNERS);
  noStroke();
  rect(plotX1,plotY1,plotX2,plotY2);
  
  image(mapImage,50,50);
  
  for (int i=0; i<numOspedali; i++) {
    interpolators[i].update();
  }
  
  // Un loop che crea i cerchi delle locations
  for(int i=0; i<numOspedali; i++) {
    float x = map(coordX[i],0,startWidth,plotX1,plotX2);
    float y = map(coordY[i],0,startHeight,plotY1,plotY2);
    float value = interpolators[i].value;
    float radius = map(value,bloodMin,bloodMax,5,30);
    
    ellipseMode(RADIUS);
    fill(#FF0000,130);
    ellipse(x,y,radius,radius);
  }
}


void updateTable() {
  for(int i=0; i<numOspedali; i++) {
    float newValue = random(0,100);
    interpolators[i].target(newValue);
  }
}

void mouseReleased() {
  updateTable();
}


class Integrator {

  final float DAMPING = 0.5f;
  final float ATTRACTION = 0.2f;

  float value;
  float vel;
  float accel;
  float force;
  float mass = 1;

  float damping = DAMPING;
  float attraction = ATTRACTION;
  boolean targeting;
  float target;

  Integrator() { }

  Integrator(float value) {
    this.value = value;
  }

  Integrator(float value, float damping, float attraction) {
    this.value = value;
    this.damping = damping;
    this.attraction = attraction;
  }

  void set(float v) {
    value = v;
  }

  void update() {
    if (targeting) {
      force += attraction * (target - value);      
    }

    accel = force / mass;
    vel = (vel + accel) * damping;
    value += vel;

    force = 0;
  }

  void target(float t) {
    targeting = true;
    target = t;
  }

  void noTarget() {
    targeting = false;
  }
}