universal gravitation
クリックすると惑星が一個増えるかも
各々が各々に判定してるから増やすとどんどん重くなる
3次元座標使ってるのに3次元表示してない
/**
* Copyright cpu_t ( http://wonderfl.net/user/cpu_t )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zb4F
*/
// クリックすると惑星が一個増えるかも
// 各々が各々に判定してるから増やすとどんどん重くなる
// 3次元座標使ってるのに3次元表示してない
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.Vector3D;
import net.hires.debug.Stats;
[SWF(width = 400, height = 400, backgroundColor = 0xFFFFFF, frameRate = 60)]
public class PlanetaryMotion extends Sprite {
private const _size:int = stage.stageWidth;
private var _satellites:Vector.<Satellite>;
private var _bmpdata:BitmapData;
private var _blurFilter:BlurFilter;
public function PlanetaryMotion() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addChild(new Stats());
_satellites = new Vector.<Satellite>;
_bmpdata = new BitmapData(_size, _size, false, 0x000000);
addChild(new Bitmap(_bmpdata));
_blurFilter = new BlurFilter(4, 4, 1);
addSatellite(new Satellite(50, new Vector3D(), new Vector3D()));
addSatellite(new Satellite(1.5, new Vector3D(-90), new Vector3D(0,-3.5)));
addSatellite(new Satellite(1.5, new Vector3D(-90.5), new Vector3D(0.5,-3.2)));
addSatellite(new Satellite(2, new Vector3D(0,190), new Vector3D(3.2)));
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function mouseDownHandler(e:Event):void
{
var pt:Vector3D = new Vector3D(mouseX - _size / 2, mouseY - _size / 2, 0);
var vel:Vector3D = new Vector3D(Math.random() * 6 - 3, Math.random() * 6 - 3, Math.random() * 6 - 3);
var st:Satellite = new Satellite(Math.random() * 2, pt, vel);
addSatellite(st);
}
private function addSatellite(st:Satellite):void
{
_satellites.push(st);
}
private function enterFrameHandler(e:Event):void
{
_bmpdata.lock();
_bmpdata.applyFilter(_bmpdata, _bmpdata.rect, _bmpdata.rect.topLeft, _blurFilter);
var lastsatellites:Vector.<Satellite> = _satellites.concat();
_satellites = _satellites.filter(function(item:Satellite, index:int, vector:Vector.<Satellite>):Boolean
{
if (index != 0) item.update(lastsatellites);
bdDrawCircle(_bmpdata, _size / 2 + item.point.x, _size / 2 + item.point.y, item.radius, 0xFFFFFF);
return (item.point.x > -_size && item.point.x < _size && item.point.y > -_size && item.point.y < _size)?true:false;
}, this);
_bmpdata.unlock();
}
private function bdDrawCircle(bmpdata:BitmapData, x:Number, y:Number, radius:Number, color:uint):void
{
var dx:Number = 0;
var dy:Number = radius;
bmpdata.setPixel(int(x + 0.5), int(y + dy + 0.5), color);
bmpdata.setPixel(int(x + 0.5), int(y - dy + 0.5), color);
bmpdata.setPixel(int(x + dy + 0.5), int(y + 0.5), color);
bmpdata.setPixel(int(x - dy + 0.5), int(y + 0.5), color);
radius *= radius;
while (dx + 1 < dy) {
dx++;
dy = Math.sqrt(radius - dx * dx);
bmpdata.setPixel(int(x + dx + 0.5), int(y + dy + 0.5), color);
bmpdata.setPixel(int(x - dx + 0.5), int(y + dy + 0.5), color);
bmpdata.setPixel(int(x + dx + 0.5), int(y - dy + 0.5), color);
bmpdata.setPixel(int(x - dx + 0.5), int(y - dy + 0.5), color);
bmpdata.setPixel(int(x + dy + 0.5), int(y + dx + 0.5), color);
bmpdata.setPixel(int(x + dy + 0.5), int(y - dx + 0.5), color);
bmpdata.setPixel(int(x - dy + 0.5), int(y + dx + 0.5), color);
bmpdata.setPixel(int(x - dy + 0.5), int(y - dx + 0.5), color);
}
}
}
}
import flash.geom.Vector3D;
class Satellite extends Object {
// Variables
private var _radius:Number;
private var _point:Vector3D;
private var _velocity:Vector3D;
// Constructor methods
public function Satellite(radius:Number, point:Vector3D, velocity:Vector3D) {
_radius = radius;
_point = point;
_velocity = velocity;
}
// Instance methods
public function update(satellites:Vector.<Satellite>):void
{
const G:Number = 1;
var r:Number;
var vec:Vector3D;
for each(var st:Satellite in satellites) {
vec = _point.subtract(st.point);
r = vec.lengthSquared * 500;
vec.normalize();
if (r != 0) vec.scaleBy( -G * (_radius*_radius*_radius) * (st.radius*st.radius*st.radius) / r);
_velocity = _velocity.add(vec);
}
_point = _point.add(_velocity);
}
// Accessor methods
public function get radius():Number { return _radius; }
public function set radius(value:Number):void { _radius = value; }
public function get point():Vector3D { return _point; }
public function set point(value:Vector3D):void { _point = value; }
public function get velocity():Vector3D { return _velocity; }
public function set velocity(value:Vector3D):void { _velocity = value; }
}