Edit in JSFiddle

// size
int height = 700;
int width = 600;

// time
int nbFramePerSec = 80;
float drawPeriod = 1/nbFramePerSec;

// ground variables -------------------------------------------
int nbSegment = 40;
Ground[] ground = new Ground[nbSegment];
float[] groundHeight = new float[nbSegment + 1];

//physics variables
float mass = 0.1; // kg
float radius = 15; // 1px = 1cm <<--------
float bounceFactor = -0.95; // dimensionless
float Cd = 0.47; // drag coef, dimensionless
float rho = 1.22; // density, kg / m^3
float ag = 9.81; // acceleration, m/s^2
float Fx, Fy, ax, ay;

// build ball -------------------------------------------
// top left corner is (x, y) = (0, 0)
// bottom right corner is (width, height) = (0, 0)
// x (cm), y (cm), vx (cm/s), vy (cm/s)
int xinit = round(width * 0.0);
int yinit = round(width * 0.95);
int vxinit = 8; // cm/s
int vyinit = -18; // cm/s
Ball ball = new Ball(xinit, yinit, vxinit, vyinit, radius, mass, bounceFactor);
float A = PI * (ball.r/100) * (ball.r/100); // surface, m^2

// setup(), executed once at inception -----------------------------------
void setup() {
  size(width, height);
  background(255);
  smooth();
  frameRate(nbFramePerSec); // frames per sec
  
 // calculate ground height for each nbSegment+1 points 
  for (int i = 0; i < groundHeight.length; i++) {
    groundHeight[i] = random(height - 45, height - 30);
  }
  
  // build ground over width of canvas, regardless of segment number
  float nbSegmentFloat = nbSegment;
  for (int i = 0; i < nbSegment; i++) {
    ground[i] = new Ground(i*width/nbSegmentFloat, groundHeight[i], (i+1)*width/nbSegmentFloat, groundHeight[i + 1]);
  }
}

void draw() {

  // display white background with opacity
  noStroke();
  fill(255, 999); // first arg is white=255, second arg is opacity 999=opaque and 0=transparent
  rect(0, 0, width, height);
    
  // draw ground
  fill(153);
  beginShape();
  for (int i = 0; i < nbSegment; i++) {
    vertex(ground[i].x1, ground[i].y1);
  }
  vertex(ground[nbSegment-1].x2, ground[nbSegment-1].y2);
  vertex(ground[nbSegment - 1].x2, height);
  vertex(ground[0].x1, height);
  endShape(CLOSE);
  
  // ball physics
  // drag force: Fd = -1/2 * Cd * A * rho * v * v
  Fx = -0.5 * Cd * A * rho * pow(ball.vx, 3) / abs(ball.vx);
  Fy = -0.5 * Cd * A * rho * pow(ball.vy, 3) / abs(ball.vy);
  //Fx = 0;
  //Fy = 0;
  
  // acceleration ( sum of forces = mass * acceleration )
  ax = Fx / ball.m;
  ay = ag + (Fy / ball.m);
  
  // Integrate to get velocity
  ball.vx += ax * drawPeriod;
  ball.vy += ay * drawPeriod;
  
  // Integrate to get position
  ball.x += ball.vx * drawPeriod * 100; // factor 100 due to x and vx defined in cm
  ball.y += ball.vy * drawPeriod * 100; // factor 100 due to x and vx defined in cm

  // draw ball
  stroke(0);
  fill(200,0,0);
  ellipse(ball.x, ball.y, ball.r * 2, ball.r * 2);

  // collision
  checkWallCollision();
  for (int i = 0; i < nbSegment; i++) {
    checkGroundCollision(ground[i]);
    
  // print out variable in console
  //println("ball.vy="+ball.vy);
  }  
}

// wall collision
void checkWallCollision() {
  // right wall
  if (ball.x > width - ball.r) {
    ball.x = width - ball.r;
    ball.vx *= ball.bounce;
  } else /* left wall */ if (ball.x < ball.r) {
    ball.x = ball.r;
    ball.vx *= ball.bounce;
  }
}

// ground collision
void checkGroundCollision(Ground groundSegment) {

  // distance ball and ground
  float deltaX = ball.x - groundSegment.x;
  float deltaY = ball.y - groundSegment.y;

  // trig values
  float cosRot = cos(groundSegment.rot);
  float sinRot = sin(groundSegment.rot);

  // rotate to ground referential
  float deltaXRefGround = cosRot * deltaX + sinRot * deltaY;
  float deltaYRefGround = cosRot * deltaY - sinRot * deltaX;
  float vxRefGround = cosRot * ball.vx + sinRot * ball.vy;
  float vyRefGround = cosRot * ball.vy - sinRot * ball.vx;

  // ground collision segment check
  if (deltaYRefGround > -ball.r && ball.x > groundSegment.x1 && ball.x < groundSegment.x2) {
    deltaYRefGround = -ball.r;
    vyRefGround *= ball.bounce;
  }

  // reset ground, velocity and orb
  deltaX = cosRot * deltaXRefGround - sinRot * deltaYRefGround;
  deltaY = cosRot * deltaYRefGround + sinRot * deltaXRefGround;
  ball.vx = cosRot * vxRefGround - sinRot * vyRefGround;
  ball.vy = cosRot * vyRefGround + sinRot * vxRefGround;
  ball.x = groundSegment.x + deltaX;
  ball.y = groundSegment.y + deltaY;
}

// Classes ----------------------------------------------------
class Ground {
  float x1, y1, x2, y2;
  float x, y, len, rot;
  
  // default constructor
  Ground() {}

  // constructor
  Ground(float x1, float y1, float x2, float y2) {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    x = (x1 + x2) / 2;
    y = (y1 + y2) / 2;
    len = dist(x1, y1, x2, y2);
    rot = atan2((y2 - y1), (x2 - x1));
  }
}

class Ball {
  float x, y, vx, vy, r, m, bounce;
  
  // default constructor
  Ball() {}

  Ball(float x, float y, float vx, float vy, float r, float m, float bounce) {
    this.x = x;
    this.y = y;
    this.vx = vx;
    this.vy = vy;
    this.r = r;
    this.m = m;
    this.bounce = bounce;
  }
}

<canvas width="600px" height="700px"></canvas>
canvas {
  display:block;
  margin:20px;
  border:1px solid #666;
}

</style>
<script type="text/javascript"> window.addEventListener('load', function() {
  var scripts=document.body.getElementsByTagName('script');
  var canvases=document.body.getElementsByTagName('canvas');
  new Processing(canvases[0], scripts[0].text);
}
, false);
// Here prevents javascript in body from throwing error
</script>
<style>