public void update() {
   for (int j = 0; j < parti_num; ++j) {
     Parti_obj obj = parti_obj[INNER][j];
     obj.x += obj.speedX;
     obj.y += obj.speedY;
     obj.speedX += obj.accX;
     obj.speedY += obj.accY;
     if (obj.x < width / 3
         || obj.x > width * 2 / 3
         || obj.y - height / 4 > height / 2 * Math.sin(((obj.x - width / 3) / Math.PI * 3 / width))
         || obj.y < 0) {
       reset(obj, INNER);
     }
   }
   for (int j = 0; j < parti_num; ++j) {
     Parti_obj obj = parti_obj[MID][j];
     obj.x += obj.speedX;
     obj.y += obj.speedY;
     obj.speedX += obj.accX;
     obj.speedY += obj.accY;
     if (obj.x >= width * 2 / 3 || obj.x <= width / 3) {
       if (obj.x < 0
           || obj.x > width
           || obj.y - height / 4 > height * 3 / 4 * Math.sin((obj.x * Math.PI / width))
           || obj.y < 0) {
         reset(obj, MID);
       }
     } else {
       if (obj.y - height / 4 > height * 3 / 4 * Math.sin((obj.x * Math.PI / width))
           || obj.y + height / 4
               < height / 2 * Math.sin(((obj.x - width / 3) / Math.PI * 3 / width))
           || obj.y < 0) {
         reset(obj, MID);
       }
     }
   }
   for (int j = 0; j < parti_num; ++j) {
     Parti_obj obj = parti_obj[OUTER][j];
     obj.x += obj.speedX;
     obj.y += obj.speedY;
     obj.speedX += obj.accX;
     obj.speedY += obj.accY;
     if (obj.x < 0
         || obj.x > width
         || obj.y - height / 4 > height * Math.sin((obj.x * Math.PI / width))
         || obj.y + height / 4 < height * 3 / 4 * Math.sin((obj.x * Math.PI / width))
         || obj.y < 0) {
       reset(obj, OUTER);
     }
   }
 }
  public void reset(Parti_obj obj, int type) {
    // initialize the inner particles
    if (type == INNER) {
      obj.x = width / 3 + (float) (width / 3 * Math.random());
      obj.y = Math.random() * height / 2 * Math.sin(((obj.x - width / 3) * Math.PI * 3 / width));
    }
    // initialize the middle particles
    else if (type == MID) {
      obj.x = (float) (width * Math.random());
      if (obj.x >= width * 2 / 3 || obj.x <= width / 3) {
        obj.y = Math.random() * height * 3 / 4 * Math.sin((obj.x * Math.PI / width));
      } else {
        obj.y =
            height / 2 * Math.sin(((obj.x - width / 3) / Math.PI * 3 / width))
                + Math.random()
                    * (height * 3 / 4 * Math.sin((obj.x * Math.PI / width))
                        - height / 2 * Math.sin(((obj.x - width / 3) / Math.PI * 3 / width)));
      }

    }
    // initialize the outer particles
    else if (type == OUTER) {
      obj.x = (float) (width * Math.random());
      obj.y =
          height * 3 / 4 * Math.sin((obj.x * Math.PI / width))
              + Math.random() * (height / 4 * Math.sin((obj.x * Math.PI / width)));
    }
    obj.life = (int) Math.random() * 100;
    if (obj.x % 2 == 0) {
      obj.speedX = 5 * Math.random();
      obj.speedY = 5 * Math.random();
    } else {
      obj.speedX = -5 * Math.random();
      obj.speedY = -5 * Math.random();
    }
    if (obj.y % 2 == 0) {
      obj.accX = Math.random();
      obj.accY = Math.random();
    } else {
      obj.accX = -Math.random();
      obj.accY = -Math.random();
    }
  }