Fl020_DotsDemo.as (Main)
/**
* @date 01/11/2008
* @author borealkiss
* @see http://boreal-kiss.com/flash/ex/50/
*/
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.geom.PerspectiveProjection;
import com.borealkiss.display.dots.Dots;
import com.borealkiss.display.dots.MultiTori;
[SWF(width="700",height="500",backgroundColor="0x0")]
public class Fl020_DotsDemo extends Sprite{
private var _projectionMatrix:Matrix3D;
private var _primitive:Dots;
private var _scene:Sprite;
private var _canvasBitmap:BitmapData;
/**
* Constructor
*/
public function Fl020_DotsDemo(){
init();
}
private function init():void{
_canvasBitmap = new BitmapData(stage.stageWidth,stage.stageHeight,false,0x0);
addChild(new Bitmap(_canvasBitmap));
_scene = new Sprite();
_scene.transform.matrix3D = new Matrix3D();
_primitive = new MultiTori(0.9,0.05,15000);
var pp:PerspectiveProjection= new PerspectiveProjection();
pp.fieldOfView = 100;
_projectionMatrix = pp.toMatrix3D();
addEventListener(Event.ENTER_FRAME,drawBitmap);
}
private function drawBitmap(e:Event):void{
rotate(_scene);
var world:Matrix3D = _scene.transform.matrix3D.clone();
world.append(_projectionMatrix);
var projectedVerts:Array = project3D(_primitive.vertices,world);
_canvasBitmap.fillRect(_canvasBitmap.rect,0x0);
for (var i:int=0; i<projectedVerts.length; i++){
var v:Vector3D = projectedVerts[i];
var x:Number = _canvasBitmap.width/2 + v.x;
var y:Number = _canvasBitmap.height/2 + v.y;
_canvasBitmap.setPixel(x,y,getColor(x,y));
}
}
private function project3D(verts:Array,world:Matrix3D):Array{
var results:Array = new Array();
for (var i:int=0; i<verts.length; i++){
var v:Vector3D = world.transformVector(verts[i]);
results.push(v);
}
return results;
}
private function rotate(target:Sprite):void{
var dx:Number = (mouseX - stage.stageWidth/2);
var dy:Number = (mouseY - stage.stageHeight/2);
target.rotationX = 0.5*dy;
target.rotationY = -0.8*dx;
}
private function getColor(x:Number,y:Number):uint{
var r:int = 255 * Math.random();
var g:int = 255*x/_canvasBitmap.width;
var b:int = 255*y/_canvasBitmap.height;
return r << 16 | g << 8 | b;
}
}
}
com.borealkis.display.dots.Dots.as (Abstract)
package com.borealkiss.display.dots{
import flash.errors.IllegalOperationError;
/**
* Abstract class.
*/
public dynamic class Dots{
protected var _vertices:Array;
public function get vertices():Array{
return _vertices;
}
public function set vertices(value:Array):void{
_vertices = value
}
/**
* Constructor
*/
public function Dots(){
if(Object(this).constructor == Dots){
throw new IllegalOperationError("Abstract class must be inherited in a subclass.");
}
}
}
}
com.borealkis.display.dots.Torus.as
package com.borealkiss.display.dots{
import flash.geom.Vector3D;
import com.borealkiss.display.dots.Dots;
public class Torus extends Dots{
protected var _majorRadius:Number;
public function get majorRadius():Number{
return _majorRadius;
}
public function set majorRadius(value:Number):void{
_majorRadius = value;
init();
}
protected var _minorRadius:Number;
public function get minorRadius():Number{
return _minorRadius;
}
public function set minorRadius(value:Number):void{
_minorRadius = value;
init();
}
protected var _totalPoints:int;
public function get totalPoints():int{
return _totalPoints;
}
/**
* Constructor
*
* @param majorRadius Major radius of a torus (i.e., radius of a donut)
* @param minorRadius Minor radius of the torus (i.e., thickness of the donut)
* @param totalPoints Total rendering points on the torus's surface.
*/
public function Torus(majorRadius:Number,minorRadius:Number,totalPoints:int){
_majorRadius = majorRadius;
_minorRadius = minorRadius;
_totalPoints = totalPoints;
init();
}
protected function init():void{
this.vertices = new Array();
for (var i:int=0; i<_totalPoints; i++){
var vertex:Vector3D = randomPlot();
this.vertices.push(vertex);
}
}
/**
* Calculate a random poit on the surface of the torus.
* @return Vector3D
*/
protected function randomPlot():Vector3D{
var majorTheta:Number = 2*Math.PI*Math.random(); var minorTheta:Number = 2*Math.PI*Math.random(); var x:Number = (_majorRadius + _minorRadius*Math.cos(minorTheta))*Math.cos(majorTheta);
var y:Number = _minorRadius*Math.sin(minorTheta);
var z:Number = (_majorRadius + _minorRadius*Math.cos(minorTheta))*Math.sin(majorTheta);
return new Vector3D(x,y,z);
}
}
}
com.borealkis.display.dots.MultiTori.as
package com.borealkiss.display.dots{
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import com.borealkiss.display.dots.Torus;
/**
* Multiple tori inheriting from Torus class.
*/
public class MultiTori extends Torus{
/**
* Constructor
*/
public function MultiTori(majorRadius:Number, minorRadius:Number, totalPoints:int){
super(majorRadius, minorRadius, totalPoints);
}
override protected function init():void{
this.vertices = new Array();
for (var i:int=0; i<_totalPoints; i++){
var vertex:Vector3D = randomPlot();
switch (i%4){
case 1:
vertex = rotateZ(vertex,45);
break;
case 2:
vertex = rotateZ(vertex,90);
break;
case 3:
vertex = rotateZ(vertex,135);
break;
}
this.vertices.push(vertex);
}
}
private function rotateZ(vector:Vector3D,degrees:Number):Vector3D{
var mat:Matrix3D = new Matrix3D();
mat.appendRotation(degrees,Vector3D.Z_AXIS);
return mat.transformVector(vector);
}
}
}
Powered by blog Boreal Kiss 2008.