projekt  
  einleitung
  applet
  quellcode
über  
  info
  team
quellcode
 
JAVADOC
SOURCECODE
import java.util.*;
import java.applet.*;

public class Physics
{
  public static Vector masses= new Vector();
  // how much seconds must proceed per frame to draw
  public static double deltaT=-1;
  private static double ONE_THIRD=1.0/3.0;

  /**
   * we need to know if deltaT is about to change to adjust the xv/yv of all
   * masses to keep their velocity
   */
  public static void setDeltaT(double dT)
  {
    if(deltaT==-1)
    { // initialize if none known
      deltaT=dT;
      return;
    }
    for(int i=0; i<masses.size(); i++)
    { // if masses exist, change their xv/yv to keep the velocity
      Mass m= (Mass)masses.get(i);
      System.out.println("mass"+i+" old: "+m.xv/deltaT);
      m.xv=(m.xv*dT)/deltaT;
      System.out.println("mass"+i+" new: "+m.xv/dT);
      m.yv=(m.yv*dT)/deltaT;
      if(m instanceof Craft)
      {
        Craft c= (Craft)m;
        c.update(dT);
      }
    }
    deltaT=dT; //.. and set the new value
  }

  /**
   * creates a new mass and returns the index of it (can be used to .get(index))
   */
  public static int addNewMass(double xP, double yP)
  {
    Mass mass= new Mass();
    mass.x= xP;
    mass.y= yP;
    //default-values
    mass.r= 45; // 0.3m
    mass.m= 1000000000000000000.0; // 10Mkg
    mass.xv= 0;
    mass.yv= 0; // mass does not move
    mass.color= Mass.getColor(masses.size()); //0=first color
    masses.add(mass);
    return masses.size()-1;
  }

  /**
   * creates a new craft, returns the index of it (can be used to .get(index))
   */
  public static int addNewCraft(double xP, double yP)
  {
    Craft craft= new Craft();
    craft.x= xP;
    craft.y= yP;
    //default-values
    craft.r= 1.5; // 3m
    craft.m= 3810; // 3810kg
    craft.xv= 0;
    craft.yv= 0; // mass does not move
    // forward-thrust and if enabled
    craft.f=120000; // Newton
    // backward-thrust and if enabled
    craft.rf=600; //Newton
    // heading
    craft.heading=0;
    // time for one rotation
    craft.yawT=12;
    // always update the a-values within for faster calculating
    craft.update(deltaT);
    craft.color= Mass.getColor(masses.size()); //0=first color
    masses.add(craft);
    return masses.size()-1;
  }

  /**
   * calculates the number of the mass which is next to given point
   * (for selection purposes)
   */
  public static int whoIsNextTo(double xP, double yP)
  {
    if(masses.size()==0) return -1;
    int minNr=-1;
    double minLength=Double.MAX_VALUE;
    for(int i=0; i<masses.size(); i++)
    {
      Mass m= (Mass)masses.get(i);
      double l =Math.sqrt(Math.pow(m.x-xP,2)+Math.pow(m.y-yP,2));
      if(l<minLength)
      {
        minNr=i;
        minLength=l;
      }
    }
    return minNr;
  }

  public static void orbit(int centralMass, int trabantMass, double radius)
  {
    if (centralMass != trabantMass)
    {
      Mass m_central= (Mass)masses.get(centralMass);
      Mass m_trabant= (Mass)masses.get(trabantMass);
      m_trabant.x= m_central.x;
      m_trabant.y= m_central.y+radius;
      double v= 0.7*Math.sqrt((6.67259E-11*m_central.m)/radius);
      m_trabant.xv= v*deltaT;
      System.out.println("\nc:"+m_central+"\nt:"+m_trabant+"\nradius:"+radius);
      System.out.println("xv_orbit: " + m_trabant.xv);
      System.out.println("v_orbit: " + v);
      m_trabant.yv= 0;
    }
  }

  /**
   * calculate the next state of the system (when the time delta-t is elapsed)
   */
  public static void calculate()
  {
    if(masses.size()!=0)
    {
      // **collision-detection of masses onto each other
      while(collisionDetected());
      // **gravity-influence of masses onto each other
      double[][] newV= new double[masses.size()][2];
      //calculate new xv/yv-pairs without altering mass.x & mass.yv
      for(int i=0; i<masses.size(); i++)
      {
        Mass mI= (Mass)masses.get(i);
        //holds the resulting v-vectors from all gravity-influences
        double xV=0;
        double yV=0;
        for(int j=0; j<masses.size(); j++)
        {
          if(j!=i)
          {
            Mass mJ= (Mass)masses.get(j);
            // (xI2J|yI2J) vector pointing from mI to mJ
            double xI2J= mJ.x-mI.x;
            double yI2J= mJ.y-mI.y;
            double d=Math.sqrt(Math.pow(xI2J,2)+Math.pow(yI2J,2));
            //the s mI would travel towards mJ if it had xv=0,yv=0
            // s=G*M*t^2 / (2*r^2)
            double s=6.67259E-11*mJ.m*Math.pow(deltaT,2)/(2*Math.pow(d,2));
            //add the full travelling-vector to resulting one
//            System.out.println(i+" to "+j+": "+s+", deltaT="+deltaT);
            xV+=s*xI2J/d;
            yV+=s*yI2J/d;
          }
        }
        // store in result-array
        newV[i][0]=xV;
        newV[i][1]=yV;
      }
      // *store new xv/yv-pairs in masses
      for(int i=0; i<masses.size(); i++)
      {
        Mass m= (Mass)masses.get(i);
//        System.out.println("xv("+i+") "
//            +((Mass)masses.get(i)).xv+"   "+newV[i][0]);
        m.xv+= newV[i][0];
//        System.out.println("yv("+i+") "
//            +((Mass)masses.get(i)).yv+"   "+newV[i][1]);
        m.yv+= newV[i][1];
        // add artificial velocity (caused through engine) to mass(=craft)
        if(m instanceof Craft)
        {
          Craft c= (Craft)m;
//          System.out.println(c.yawL+":"+c.yawR+":"+c.boost+":"+c.retro);
          if(c.yawL)
          {
            c.heading+= c.yawDegree;
          }
          else if(c.yawR)
          {
            c.heading-= c.yawDegree;
          }
          if(c.boost)
          { //forwart-thrust
            double d= (c.a*Math.pow(deltaT,2))/2;
            m.xv+= d*Math.cos(c.heading);
            m.yv+= d*Math.sin(c.heading);
          }
          else if(c.retro)
          { //reverse-thrust
            double d= (c.ra*Math.pow(deltaT,2))/2;
            //m.xv+= d*Math.cos(c.heading+(2*Math.PI));
            //m.yv+= d*Math.sin(c.heading+(2*Math.PI));
            m.xv-= d*Math.cos(c.heading);
            m.yv-= d*Math.sin(c.heading);			
			
          }
        }
        //move it! ;)
        m.x+=m.xv;
        m.y+=m.yv;
      }
    }
  }

  private static boolean collisionDetected()
  {
    for(int i=0; i<masses.size(); i++)
    {
      Mass mI= (Mass)masses.get(i);
      for(int j=0; j<masses.size(); j++)
      {
        if(j!=i)
        {
          Mass mJ= (Mass)masses.get(j);
          // (xI2J|yI2J) vector pointing from mI to mJ
          double xI2J= mJ.x-mI.x;
          double yI2J= mJ.y-mI.y;
          double d=Math.sqrt(Math.pow(xI2J,2)+Math.pow(yI2J,2));
          if(d<=(mI.r+mJ.r))
          {
            Mass m=new Mass();
            //volume of sphere of mI
            double volI= (4*Math.pow(mI.r,3)*Math.PI)/3;
            double volJ= (4*Math.pow(mJ.r,3)*Math.PI)/3;
            System.out.println(volI+":"+volJ);
            double vol=volI+volJ;
            // the two volumes "melt" into one (get the radius of this one)
            m.r= Math.pow(vol*3/(4*Math.PI),ONE_THIRD); // 1/3 = compilererror
            System.out.println("r"+mI.r);
            //calculate xv/yv
            // completely nonelastic collision
            m.xv= ((mI.m*mI.xv)+(mJ.m*mJ.xv))/(mI.m+mJ.m);
            m.yv= ((mI.m*mI.yv)+(mJ.m*mJ.yv))/(mI.m+mJ.m);
            //calculate x/y
            // geometric invers proportional than previous state
            m.x= mI.x+( ((mJ.x-mI.x)*mJ.r)/(m.r+mJ.r) );
            m.y= mJ.y+( ((mJ.y-mI.y)*mJ.r)/(m.r+mJ.r) );
            //calculate m
            m.m= mI.m+mJ.m;
            if(volI<volJ) m.color= mJ.color;
              else m.color= mI.color;
            //play "crash sound"
            if(mI instanceof Craft || mJ instanceof Craft)
            {
              Main.crash.play();
            }
            else
            {
              Main.collision.play();
            }
            System.out.println(MassPanel.getActiveMass()+", j="+j);
            if(MassPanel.getActiveMass()==j || MassPanel.getActiveMass()==-1)
            {
              MassPanel.update(i);
              //ControlPanel.update();
            }
            masses.remove(mI);
            masses.remove(mJ);
            masses.add(m);
            MassPanel.update(masses.size()-1);
            return true;
          }
        }
      }
    }
    return false;
  }

}