/*	Rocket Simulation Module*/import Vec3D;import Planet;class Rocket{	/*	A Rocket is an object which has a certain position and velocity,		and is imbedded in a certain environment.  On each Update(),		it can query its environment for external forces, calculate		forces (thrust) it exerts itself, and updates its state.	*/	public Planet	itsPlanet;		// planet it is bound to	public double	mass;			// current total mass	public double	fuel_mass;		// current mass of fuel	public double	V_exhaust;		// current exhaust velocity	public double	exhaust_rate;	// current mass of exhaust per sec	public double	cd;				// coefficient of drag	public double	area;			// frontal area	public Vec3D	position;		// position relative to center of planet	public Vec3D	velocity;		// current velocity	public Rocket(Planet pPlanet) {		itsPlanet = pPlanet;		position = new Vec3D(0, itsPlanet.radius, 0);		velocity = new Vec3D();		mass = 1;		cd = 0.3;		area = 5;	}	public void Update() { Update(1.0); }	// sure wish we had default values...		public void Update( double dt ) {		// As this is the first attempt, I'll use a very simple		// forward Euler integration approach.				// First, get the total forces on the rocket.				// Gravity is calculated by the planet, given our position & mass.		Vec3D Fgrav = itsPlanet.GetGravity( position, mass );				// Thrust is a result of whatever mass we're expelling.		// For now, we assume we're going straight up (+Y).		double thrust = V_exhaust * exhaust_rate;		Vec3D Fthrust = new Vec3D(0, thrust, 0);		// Drag is opposite in direction to the current velocity,		// and has a complex magnitude computed by the Planet.		double speed = velocity.Length();		Vec3D Fdrag;		if (speed > 0)			Fdrag = velocity.Times( - itsPlanet.GetAirDrag(				position, velocity, cd, area ) / speed );		else Fdrag = new Vec3D();				// Add the forces together, then do a = F/m, and apply a.		Vec3D Ftotal = Fgrav.Plus(Fthrust).Plus(Fdrag);		Vec3D accel = Ftotal.DividedBy(mass);				// actually update our state variables		velocity.Add( accel.Times(dt) );		position.Add( velocity.Times(dt) );				mass -= exhaust_rate * dt;		fuel_mass -= exhaust_rate * dt;		if (fuel_mass < exhaust_rate * dt)			exhaust_rate = fuel_mass / dt;		// check for crash/landing		if (position.Length() < itsPlanet.radius) {			velocity.Set(0,0,0);			// later: do something more intelligent here		}	}}class test {	static public void main(String argv[]) {		System.out.println("simulation started");		Planet Earth = new Planet();		Rocket r = new Rocket(Earth);		r.mass = 120;		r.fuel_mass = 100;		r.cd = 0.1;		// light the engines!		r.exhaust_rate = 1;		// burn 1 kg/sec		r.V_exhaust = 2000;		// exhaust speed (in m/s)		Rocket r2 = new Rocket(Earth);	// for comparison, another rocket 34km up		r2.position.y += 34000;		r2.mass = 120;		r2.fuel_mass = 100;		r2.cd = 0.1;			// totally frictionless surface!		// light the engines!		r2.exhaust_rate = 1;		// burn 1 kg/sec		r2.V_exhaust = 2000;		// exhaust speed (in m/s)		System.out.println("t\tvel.1\talt.1\tvel.2\talt.2");		for (int i=0; i < 500; i++) {			double altitude = r.position.y - Earth.radius;			if (altitude < 0) {				altitude = 0;				if (r.fuel_mass <= 0) i = 99999;			}						System.out.println( "" + i + "\t" + 				r.velocity.y + "\t" +				altitude + "\t" + 				r2.velocity.y + "\t" +				(r2.position.y - Earth.radius)				 );			for (int j=0; j<100; j++) {				r.Update( 0.01 );				r2.Update( 0.01 );			}		}	}}