3D galaxy collision
/* @author Thy
* 2 galaxy colision, all by gravity.
*/
/**
* Copyright Thy ( http://wonderfl.net/user/Thy )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/n2OQ
*/
// forked from Thy's forked from: 3D cube
// forked from Thy's 3D cube
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.text.TextField;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
//
import com.bit101.components.*;
/* @author Thy
* 2 galaxy colision, all by gravity.
*/
public class Main extends Sprite
{
private var // 3D cene objects
space:Ob = new Ob(),
camera:Cam = new Cam();
private var // ui
slide1:HUISlider,
slide2:HUISlider,
slide3:HUISlider,
slide4:HUISlider;
private const // const degree to radians proportion
rads:Number = Math.PI / 180;
private var
data:BitmapData = new BitmapData(stage.stageWidth,
stage.stageHeight - 80, false, 0),
bm:Bitmap = new Bitmap(data, "auto", true);
public function Main():void
{
// camera settings
camera.z = -10;
camera.focal = 50;
camera.offsetX = stage.stageWidth*.5;
camera.offsetY = stage.stageHeight*.5;
// box
this.addChild(bm);
bm.y = 80;
// (note that I already added the box to the display list)
var i:int = 0, l:int = 100; // how many stars
var p:P = new P(0,0,0);
var v:Number, dx:Number, dy:Number, dz:Number, d:Number;
space.points.push(p);
while(++i < l)
{
p = new P(
dx = Math.cos(i*.1) * i * 30,
dy = (Math.random()-.5)*100,
dz = Math.sin(i * .1) * i * 30);
d = Math.sqrt(dx*dx+dy*dy+dz*dz);
v = Math.sqrt(40000000 / d);
p.vx = -v * dz / d;
p.vy = v * dy / d;
p.vz = v * dx / d;
p.mass = 1;
space.points.push(p);
}
space.points[0].mass = 40000000;
i = 0;
var off:Number = 9000;
p = new P(off, off, off);
p.mass = 40000000;
space.points.push(p);
while(++i < l)
{
p = new P(
dx = Math.cos(i*.1) * i * 30 + off,
dy = Math.sin(i*.1) * i * 30 + off,
dz = (Math.random()-.5)*100 + off) ;
d = Math.sqrt((dx-=off)*dx+(dy-=off)*dy+(dz-=off)*dz);
v = Math.sqrt(40000000 / d);
p.vx = -v * dy / d;
p.vy = v * dx / d;
p.vz = v * dz / d;
p.mass = 1;
space.points.push(p);
}
// event
stage.addEventListener(Event.ENTER_FRAME, ef);
// ui
slide1 = new HUISlider(this, 0,0, "pitch");
slide2 = new HUISlider(this, 0,20,"yaw ");
slide3 = new HUISlider(this, 0,40,"roll ");
slide4 = new HUISlider(this, 0, 60, "nothin"/*"focal length"*/);
slide1.width = slide2.width = slide3.width =
slide4.width = stage.stageWidth;
slide1.maximum = slide2.maximum = slide3.maximum = 360;
slide4.maximum = 500;
slide1.value = 90;
slide2.value = 0;
slide3.value = 0;
}
private function ef(e:Event):void
{
// rotate the object box, NOT the camera
space.pitch = slide1.value * rads;
space.yaw = slide2.value * rads;
space.roll = slide3.value * rads;
// angles were in degree, so we get the radians
// set the camera focal length
camera.focal = slide4.value;
// move the 3D galaxy
move3D(space);
// do 3D to 2D conversion
get2D(space, camera);
// draw the especific galaxy
data.lock();
data.fillRect(data.rect, 0);
draw(space, camera, data);
data.unlock();
}
private function move3D(ob:Ob = null):void
{
var i:int = -1, j:int, l:int = ob.points.length;
var p:P, p2:P;
var d:Number, dx:Number, dy:Number, dz:Number, v:Number, v2:Number;
while(++i < l)
{
p = ob.points[i];
j = i;
while(++j < l)
{
p2 = ob.points[j];
d = (dx = (p.x - p2.x)) * dx +
(dy = (p.y - p2.y)) * dy +
(dz = (p.z - p2.z)) * dz;
v = p2.mass / (d);
v2 = p.mass / (d);
d = Math.sqrt(d);
dx /= d;
dy /= d;
dz /= d;
p.vx -= v * dx;
p.vy -= v * dy;
p.vz -= v * dz;
p2.vx += v2 * dx;
p2.vy += v2 * dy;
p2.vz += v2 * dz;
}
}
i = -1;
while (++i < l)
{
p = ob.points[i];
p.x += p.vx;
p.y += p.vy;
p.z += p.vz;
}
}
private function get2D(ob:Ob = null, cam:Cam = null):void
{
// get the 2D coord of all points, incluing the rotation
var i:int = -1, l:int = ob.points.length, p:P;
var a1:Number, a2:Number, b1:Number, b2:Number,
c1:Number, c2:Number;
var X:Number, Y:Number, Z:Number,
r1:Number = ob.pitch,
r2:Number = ob.yaw,
r3:Number = ob.roll;
var sr1:Number = Math.sin(r1),
cr1:Number = Math.cos(r1),
sr2:Number = Math.sin(r2),
cr2:Number = Math.cos(r2),
sr3:Number = Math.sin(r3),
cr3:Number = Math.cos(r3);
while(++i < l)
{
p = ob.points[i];
X = p.x - cam.x;
Y = p.y - cam.y;
Z = p.z - cam.z;
a1 = cr1*p.y - sr1*p.z; // pitch (x)
a2 = sr1*p.y + cr1*p.z;
b1 = cr2*a2 - sr2*p.x; // yaw (y)
b2 = sr2*a2 + cr2*p.x;
c1 = cr3*b2 - sr3*a1; // roll (z)
c2 = sr3*b2 + cr3*a1;
if(b1 > 0 || true)
{
p.scale = cam.focal / (cam.focal + b1)
p.X = c1 * .02 /*p.scale*/ + cam.offsetX;
p.Y = c2 * .02 /*p.scale*/ + cam.offsetY;
} else
{
p.scale = cam.focal / (cam.focal + b1)
p.X = 0;
p.Y = 0;
}
}
}
private function draw(ob:Ob = null, cam:Cam = null,
d:BitmapData = null):void
{
// draw the especific galaxy
var i:int = -1, l:int = ob.points.length;
var p:P;
while(++i < l)
{
p = ob.points[i];
data.setPixel(p.X, p.Y, 0xFFFFFF);
}
}
}
}
import flash.display.Sprite;
class P{
public var // position
x:Number = 0, y:Number = 0, z:Number = 0,
X:Number = 0, Y:Number = 0, scale:Number = 0;
public var // velocity
vx:Number = 0, vy:Number = 0,
vz:Number = 0;
public var // each point will be an star
mass:int = 1;
public function P(x:Number = 0, y:Number = 0, z:Number = 0)
{
this.x = x; this.y = y; this.z = z;
}
}
class Ob {
public var
points:Vector.<P> = new Vector.<P>(),
pitch:Number = 0, yaw:Number = 0, roll:Number = 0;
}
class Cam{
public var
x:Number = 0, y:Number = 0, z:Number = 0,
// I STILL DONT UNDERSTAND THE *CAMERA* ROTATIONS, only the *OBJECT* ones
//pitch:Number = 0, yaw:Number = 0, roll:Number = 0, //
focal:Number = 0, offsetX:Number = 0, offsetY:Number = 0;
}