import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; import netscape.javascript.*; import javax.comm.*; import javax.sound.midi.*; import javax.sound.midi.spi.*; import javax.sound.sampled.*; import javax.sound.sampled.spi.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.sax.*; import javax.xml.transform.stream.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; public class collisions2 extends BApplet {//bounce

float bounce = 1.9f;
float air = 1.01f;
int maxparts = 20;
//float totalparts = 0;
float grav = .09f;

ball[] objball;

class ball{
  float diameter, xpos, ypos, xv, yv, xvwas, yvwas, mass;
  int index;
  void updateVelocity(){
    yv += grav;
    if (ypos + yv + (diameter/2) > height || ypos + yv - (diameter/2) < 0){ //bounce off edge of window
      yv = -yv/bounce;
    }
    if (xpos + xv + (diameter/2) > width || xpos + xv - (diameter/2) < 0){
      xv = -xv/bounce;
    }
    for(int i=0; i < maxparts; i++){
      if (i != index){
        float xdif = xpos + xv - objball[i].xpos;// + objball[i].xv;
        float ydif = ypos + yv - objball[i].ypos;// + objball[i].yv;
        float tdif = sqrt(sq(xdif)+sq(ydif));
        float tdia = objball[i].diameter/2 + diameter/2;
        if (tdif < tdia){
          //impacta = Math.asin(distance * Math.sin((Math.atan((c1.yv - c2.yv) / (c1.xv - c2.xv))) - (Math.atan((c2._y - c1._y) / (c2._x - c1._x)))) / (c1.rad+ c2.rad));
          float thing1 = 1/(tan((objball[i].ypos - ypos) / (objball[i].xpos - xpos)));
          float thing2 = 1/(tan((yv - objball[i].yv) / (xv - objball[i].xv)));
          float impacta = 1/(sin(tdif * sin(thing2 - thing1) / (diameter + objball[i].diameter)));
          //println("thing2= "+(xv - objball[i].xv));
          //a = Math.tan(Math.atan((c1.yv - c2.yv)/(c1.xv - c2.xv)) + impacta);
          float a = tan(1/(tan((yv - objball[i].yv)/(xv - objball[i].xv))) + impacta);
          //c2.xv = (c2.xvwas + (2*(c1.xv - c2.xv + (a*(c1.yv - c2.yv))) / ((1+(a*a))*(1+(c2.m/c1.m))))) / bounce;
	  //c2.yv = (c2.yvwas + (a*(c2.xv - c2.xvwas))) / bounce;
	  //c1.xv = (c1.xvwas - (c2.m / c1.m *(c2.xv -  - c2.xvwas))) / bounce;
	  //c1.yv = (c2.yvwas - (a * c2.m / c1.m *(c2.xv -  - c2.xvwas))) / bounce;
          xvwas = xv;
          yvwas = yv;
          objball[i].xvwas = objball[i].xv;
          objball[i].yvwas = objball[i].yv;
	  objball[i].xv = (objball[i].xv + (2*(xv - objball[i].xv + (a*(yv - objball[i].yv))) / ((1 + (sq(a)) * (1 + (objball[i].mass/mass)))))) / bounce;
          objball[i].yv = (objball[i].yv + (a*(objball[i].xv - objball[i].xvwas))) / bounce;
          xv = (xvwas - (objball[i].mass / mass * (objball[i].xv + objball[i].xvwas))) / bounce;
          yv = (yvwas - (a * objball[i].mass / mass * (objball[i].xv + objball[i].xvwas))) / bounce;			
        }
      }  
    }
  }
  void updatePosition(){
    xpos += xv;
    ypos += yv;
  }
  void drawshape(){
    ellipse(xpos, ypos, diameter, diameter);
  }
}

void setup(){
  framerate(100);
  println("new run -----------------------------------------------");
  ellipseMode(CENTER_DIAMETER);
  size(600, 400);
  objball = new ball[maxparts];
  colorMode(HSB);
  noStroke();
  background(0, 100, 140);
  fill(20, 230, 150); 
  for(int i=0; i < maxparts; i++){
    objball[i] = new ball();
    objball[i].diameter = random(30)+5;
    objball[i].xpos = random(500)+50;
    objball[i].ypos = random(50);
    objball[i].mass = objball[i].diameter;
    objball[i].yv = grav;
    objball[i].xv = random(2); 
    objball[i].index = i;
    objball[i].drawshape();
  }
}
void loop(){
 // background(100);
  for(int i = 0; i < width; i++){
    for(int j = 0; j < height; j++){
      int pix = get(i, j);
      pix = color(hue(pix), saturation(pix) - 10, brightness(pix));
      set(i, j, pix);
    }
  }
  for(int i=0; i < maxparts; i++){
    objball[i].updateVelocity();
    objball[i].updatePosition();
    objball[i].drawshape();
  }
}





}