package example.orbit.force { import org.generalrelativity.foam.dynamics.element.ISimulatable; import org.generalrelativity.foam.math.Vector; import org.generalrelativity.foam.dynamics.force.IForceGenerator; import org.generalrelativity.foam.dynamics.enum.Simplification; public class GravitationalForceGenerator implements IForceGenerator { /** gravitational constant **/ protected var g:Number; /** source of gravitational pull (references mass) **/ protected var source:ISimulatable; /** * Creates the Force Generator * * @param source source of gravitational pull * @param gravitationalConstant magic constant (trial and error per simulation) * * @throws ArgumentError if source has infinite mass * */ public function GravitationalForceGenerator( source:ISimulatable, gravitationalConstant:Number = 1.2 ) { //if the source's mass is infinite, we'll break the simulation- throw an error if( source.mass == Simplification.INFINITE_MASS ) throw new ArgumentError( "Infinite mass breaks this force generator" ); this.source = source; g = gravitationalConstant; } /** * Generates the gravitational force on the supplied element * *

* We find the source through the following equation: *

		 * F = G * m1 * m2 / r^2
		 * 
* where: *
		 * F is the force we're solving for (applied along the bodies' difference vector)
		 * G is a gravitational constant
		 * m1/m2 are the masses involved in the exchange (here, the force is only applied to element)
		 * r is the distance between the bodies
		 * 

* * @param element ISimulatable to apply force to * */ public function generate( element:ISimulatable ) : void { //find the difference vector var diff:Vector = source.position.minus( element.position ); //add our solved force along the difference vector to the supplied element element.addForce( diff.getUnit().times( g * source.mass * element.mass / diff.dot( diff ) ) ); } } }