Newtonian Gravitation
Newton's Law of [Universal] Gravitation:
F = (g * (m1*m2 / r^2))
Click and drag either sprite to observe Newtonian Gravitation
Improper (by some margin.. eg: Still using some trace amounts of flow control -> stopping sprite at edge of radius)
This is also still incorrect by some degree but a much more adamant solution in comparison to previous gravitational simulations I have written.
The pseudo-mass variables within this algorithm are using position and sprite radius to determine their magnitude, which makes for interesting results (planet-size sprites have much, much stronger gravitation)
Although Newtonian gravitation is no longer true in physical application/examination, it is quite a close estimation of how gravity works. Einstein's investigations into gravity are much more spot on though - relativity is today's contemporary Occam's Razor since it holds true beyond instances that Newton's formula could not apply to
TODO:
-Write 'Forces' class
-Optimize ALL math
♥2 |
Line 174 |
Modified 2014-11-22 09:06:20 |
MIT License
archived:2017-03-04 18:52:06
ActionScript3 source code
/**
* Copyright hemingway ( http://wonderfl.net/user/hemingway )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/qSz1
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.*;
[SWF(frameRate = 60, width = 465, height = 465)]
public class Newton extends Sprite
{
public static const G:Number = 3;
internal var gravBody :GravBody;
public var bodyArray:Array = [gravBody, gravBody, gravBody, gravBody, gravBody];
public function Newton()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
public function _init() :void
{
for (var $children:Number = 0; $children < bodyArray.length; $children++)
{bodyArray[$children] = new GravBody(bodyArray, Math.random() * 465, Math.random() * 465, 4 + Math.random()*60); addChild(bodyArray[$children]);}
//graphics.clear ();
//graphics.lineStyle (1, 0, 0.75);
//graphics.drawRect (0, 0, 462, 464);
}
public function addedToStage($e:Event) :void
{
stage.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
_init();
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
class GravBody extends Sprite
{
protected var _c:Number;
protected var _a:Number;
protected var _x:Number;
protected var _y:Number;
protected var _r:Number;
protected var _vX:Number;
protected var _vY:Number;
private var _drag:Boolean = false;
internal var bodyArray:Array;
public function GravBody($bodyArray:Array, $x:Number = 232.5, $y:Number = 232.5, $r:Number = 20, $c:Number = 0, $a:Number = 0.5)
{
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
bodyArray = $bodyArray;
_c = $c;
_a = $a;
_x = $x;
_y = $y;
_r = $r;
}
public function _init() :void
{
graphics.clear ();
graphics.beginFill (_c, _a);
graphics.drawCircle (_x, _y, _r);
}
public function addedToStage($e:Event) :void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
_init();
}
internal var oldPoint :Point = new Point();
internal var newPoint :Point = new Point();
internal var clcPoint :Point = new Point();
public function onMouseDown($e:MouseEvent) :void
{
oldPoint = new Point($e.stageX, $e.stageY);
_drag = true;
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
public function onMouseMove($e:MouseEvent) :void
{
newPoint = new Point($e.stageX, $e.stageY);
clcPoint = Point(newPoint.subtract(oldPoint));
x += clcPoint.x;
y += clcPoint.y;
oldPoint = newPoint;
}
public function onMouseUp($e:MouseEvent) :void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
_drag = false;
}
public function onEnterFrame($e:Event) :void
{
applyForces(bodyArray)
}
public function applyForces($array:Array) :void
{
if ($array.length > 1)
{
for (var $index:Number = 0; $index < $array.length; $index++)
{
if (this != $array[$index])
{
var body1:GravBody = this;
var body2:GravBody = $array[$index];
var $sum :Number = (body1.radius + body2.radius);
var $distX1 :Number = (body2.x - body1.x);
var $distY1 :Number = (body2.y - body1.y);
var $distX2 :Number = (body1.x - body2.x);
var $distY2 :Number = (body1.y - body2.y);
var $dist1 :Number = Point.distance(new Point(body1.x, body1.y), new Point(body2.x, body2.y));
var $dist2 :Number = Point.distance(new Point(body2.x, body2.y), new Point(body1.x, body1.y));
var $forceX1 :Number = ($distX1 / $dist1);
var $forceY1 :Number = ($distY1 / $dist1);
var $forceX2 :Number = ($distX2 / $dist2);
var $forceY2 :Number = ($distY2 / $dist2);
var $force1 :Number = ($dist1 - $sum);
var $force2 :Number = ($dist2 - $sum);
var $mass1 :Point = new Point((body2.x - body1.x) * body2.radius, (body2.y - body1.y) * body2.radius);
var $mass2 :Point = new Point((body1.x - body2.x) * body1.radius, (body1.y - body2.y) * body1.radius);
body1.vX = Newton.G * ($mass1.x / Math.pow(($dist1 + $sum), 2));
body1.vY = Newton.G * ($mass1.y / Math.pow(($dist1 + $sum), 2));
body2.vX = Newton.G * ($mass2.x / Math.pow(($dist2 + $sum), 2));
body2.vY = Newton.G * ($mass2.y / Math.pow(($dist2 + $sum), 2));
if (!body1.drag && !body2.drag)
{
x += (clcPoint.x / 64);
y += (clcPoint.y / 64);
if ((($force1 + $force2) / 2) >= 0)
{
body1.x += body1.vX;
body1.y += body1.vY;
body2.x += body2.vX;
body2.y += body2.vY;
}else{
body1.x += ($force1 * $forceX1);
body1.y += ($force1 * $forceY1);
body2.x += ($force2 * $forceX2);
body2.y += ($force2 * $forceY2);
}
}
}
}
}
}
public function get color() :Number
{ return _c }
public override function get alpha() :Number
{ return _a }
public override function get x() :Number
{ return _x }
public override function get y() :Number
{ return _y }
public function get radius() :Number
{ return _r }
public function get vX() :Number
{ return _vX }
public function get vY() :Number
{ return _vY }
public function get drag() :Boolean
{ return _drag }
public function set color($value:Number) :void
{ _c = $value; _init(); }
public override function set alpha($value:Number) :void
{ _a = $value; _init(); }
public override function set x($value:Number) :void
{ _x = $value; _init(); }
public override function set y($value:Number) :void
{ _y = $value; _init(); }
public function set radius($value:Number) :void
{ _r = $value; _init(); }
public function set vX($value:Number) :void
{ _vX = $value; _init(); }
public function set vY($value:Number) :void
{ _vY = $value; _init(); }
}