Neon Sphere Aquioux forked:5favorite:23lines:262license : MIT License modified : 2012-03-08 20:43:26 Embed Tweet package { import flash.display.Sprite; import flash.events.Event; [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#000000")] /** * Neon Sphere * @author YOSHIDA, Akio(Aquioux) */ public class Main extends Sprite { private var viewer_:Viewer; // ビューア public function Main() { setup(); addEventListener(Event.ENTER_FRAME, update); } // セットアップ private function setup():void { // ステージサイズ var w:int = stage.stageWidth; var h:int = stage.stageHeight; // 球座標の経度緯度それぞれの分割数 var longitude:int = 36; var latitude:int = longitude * 2; // 座標データ生成クラス初期化 CreateData.setup(longitude, latitude, 150); // プロジェクションクラス初期化 Projection.offsetX = w / 2; Projection.offsetY = h / 2; Projection.offsetZ = 500; Projection.longitude = longitude; Projection.latitude = latitude; Projection.setup(CreateData.data); // マウス挙動クラス初期化 MouseBehavior.setup(this); // ビューアの作成 viewer_ = new Viewer(w, h); viewer_.buttonMode = true; addChild(viewer_); } // アップデート private function update(e:Event):void { MouseBehavior.update(); viewer_.update(Projection.update(MouseBehavior.moveX, MouseBehavior.moveY)); } } } //package { /** * 座標データ生成クラス * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class CreateData { /** * 座標データ Vector */ static public function get data():Vector.<Number> { return _data; } static private var _data:Vector.<Number>; /** * セットアップ */ static public function setup(longitude:int, latitude:int, scale:int):void { _data = new Vector.<Number>(); var xRadian:Number = Math.PI * 2 / longitude; latitude++; // 極点を省くため var yRadian:Number = Math.PI / latitude; for (var y:int = 1; y < latitude; y++) { for (var x:int = 0; x < longitude; x++) { var px:Number = scale * Math.sin(yRadian * y) * Math.cos(xRadian * x); var py:Number = scale * Math.cos(yRadian * y); var pz:Number = scale * Math.sin(yRadian * y) * Math.sin(xRadian * x); _data.push(px, py, pz); } } _data.fixed = true; } } //} //package { //import aquioux.display.colorUtil.CycleRGB; import flash.geom.Matrix3D; import flash.geom.PerspectiveProjection; import flash.geom.Utils3D; import flash.geom.Vector3D; /** * 三次元座標を二次元座標に投射する * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Projection { /** * X座標オフセット値 */ static public function get offsetX():Number { return _offsetX; } static public function set offsetX(value:Number):void { _offsetX = value; } static private var _offsetX:Number = 0; /** * Y座標オフセット値 */ static public function get offsetY():Number { return _offsetY; } static public function set offsetY(value:Number):void { _offsetY = value; } static private var _offsetY:Number = 0; /** * Z座標オフセット値 */ static public function get offsetZ():Number { return _offsetZ; } static public function set offsetZ(value:Number):void { _offsetZ = value; zLevel_ = 1 / value; } static private var _offsetZ:Number = 500; /** * 経度方向分割数 */ static public function get longitude():int { return _longitude; } static public function set longitude(value:int):void { _longitude = value; //colorOffset_ = 360 / (value + 1); } static private var _longitude:int; /** * 経度方向分割数 */ static public function get latitude():int { return _latitude; } static public function set latitude(value:int):void { _latitude = value; colorOffset_ = 360 / (value + 2); } static private var _latitude:int; // 座標 Vecotr static private var verts_:Vector.<Number>; // 三次元座標 static private var projectedVerts_:Vector.<Number>; // 二次元投射後 static private var uvts_:Vector.<Number>; // uvts static private var data_:Vector.<Number>; // #update の返値 // パースペクティブ・プロジェクション static private var projection_:PerspectiveProjection; static private var projectionMatrix3D_:Matrix3D; // 回転計算用マトリクス static private var matrix_:Matrix3D; // 移動量保持 static private var vx_:Number = 0; static private var vy_:Number = 0; // 色関連 static private var colorOffset_:Number = 360 / (_longitude + 1); static private var colorShift_:int = 0; // z座標関連 static private var zLevel_:Number = 1 / _offsetZ; /** * セットアップ * @param data 三次元座標データ */ static public function setup(verts:Vector.<Number>):void { // 座標 Vecotr verts_ = verts; var n:uint = verts_.length; projectedVerts_ = new Vector.<Number>(n * 2 / 3, true); uvts_ = new Vector.<Number>(n, true); data_ = new Vector.<Number>(n, true); // パースペクティブ・プロジェクション projection_ = new PerspectiveProjection(); projectionMatrix3D_ = projection_.toMatrix3D(); // 回転計算用マトリクス matrix_ = new Matrix3D(); } /** * アップデート * @param moveX 移動量(X軸方向) * @param moveY 移動量(Y軸方向) * @return 三次元座標を投射した二次元座標データ */ static public function update(moveX:Number, moveY:Number):Vector.<Number> { // 外部からの移動量 moveX、moveY を内部の移動量変数 vx_、vy_ に加算 vx_ -= moveX; vy_ += moveY; // マトリクス計算 matrix_.identity(); matrix_.appendRotation(vy_, Vector3D.X_AXIS); matrix_.appendRotation(vx_, Vector3D.Y_AXIS); matrix_.appendTranslation(0, 0, _offsetZ); matrix_.append(projectionMatrix3D_); // 座標データに回転を適用 Utils3D.projectVectors(matrix_, verts_, projectedVerts_, uvts_); // sort var array:Array = []; var currentLongitude:int = 0; var currentLatitude:int = 0; var len:int = projectedVerts_.length / 2; for (var i:int = 0; i < len; i++) { var vertex:Vertex = new Vertex(); vertex.x = projectedVerts_[i * 2] + _offsetX; vertex.y = projectedVerts_[i * 2 + 1] + _offsetY; vertex.z = uvts_[i * 3 + 2]; vertex.longitude = currentLongitude; vertex.latitude = currentLatitude; array[i] = vertex; currentLongitude++; currentLongitude %= _longitude; if (currentLongitude == 0) currentLatitude++; } array.sortOn("z", Array.NUMERIC); // 返値生成 data_.fixed = false; data_.length = 0; colorShift_ += 5; len = i; for (i = 0; i < len; i++) { vertex = array[i]; var alpha:uint = vertex.z < zLevel_ ? 0x33 : 0xFF; //var c:uint = CycleRGB.getColor(vertex.longitude * colorOffset_ + colorShift_); var c:uint = CycleRGB.getColor(vertex.latitude * colorOffset_ +colorShift_); var color:uint = alpha << 24 | c; data_.push(vertex.x, vertex.y, Number(color)); } data_.fixed = true; return data_; } } //} //package { import flash.display.DisplayObject; import flash.events.MouseEvent; /** * ビューア * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class MouseBehavior { // MOUSW_MOVE による移動量 static public function get moveX():Number { return _moveX; } static private var _moveX:Number = 0; static public function get moveY():Number { return _moveY; } static private var _moveY:Number = 0; // 前回の MOUSW_MOVE 時のマウス座標 static private var prevMouseX_:Number = 0; static private var prevMouseY_:Number = 0; // マウスをダウンしているか否か static private var isMouseDown_:Boolean = false; // 摩擦係数 static private var friction_:Number = 0.98; // マウスイベントを addEvent する対象 static private var target_:DisplayObject; /** * セットアップ */ static public function setup(target:DisplayObject):void { target_ = target; target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); target.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); target.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); } // マウスハンドラ static private function mouseDownHandler(e:MouseEvent):void { isMouseDown_ = true; } static private function mouseUpHandler(e:MouseEvent):void { isMouseDown_ = false; } static private function mouseMoveHandler(e:MouseEvent):void { if (!isMouseDown_) { prevMouseX_ = target_.mouseX; prevMouseY_ = target_.mouseY; } } /** * アップデート */ static public function update():void { if (isMouseDown_) { _moveX = target_.mouseX - prevMouseX_; _moveY = target_.mouseY - prevMouseY_; prevMouseX_ = target_.mouseX; prevMouseY_ = target_.mouseY; } else { _moveX *= friction_; _moveY *= friction_; } } } //} //package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter; import flash.geom.ColorTransform; import flash.geom.Point; import flash.geom.Rectangle; /** * ビューア * @author YOSHIDA, Akio(Aquioux) */ /*public*/ class Viewer extends Sprite { //フェードアウトのための定義 private const FADE:ColorTransform = new ColorTransform(0.999, 0.999, 0.999); private const BLUR:BlurFilter = new BlurFilter(4, 4, BitmapFilterQuality.HIGH); // BitmapData 関連 private var bmd_:BitmapData; // 表示 BitmapData private var bufferBmd_:BitmapData; // バッファ private var rect_:Rectangle; // ColorTransform, Blur 共用 private const ZERO_POINT:Point = new Point(0, 0); private var start_:int = 0; /** * コンストラクタ * @param sw ステージ幅 * @param sh ステージ高 */ public function Viewer(sw:int, sh:int) { // BitmapData 関連 bufferBmd_ = new BitmapData(sw, sh, true, 0xFF000000); bmd_ = bufferBmd_.clone(); rect_ = bmd_.rect; addChild(new Bitmap(bmd_)); } /** * アップデート * @param data 描画座標データ */ public function update(data:Vector.<Number>):void { // bufferBmd_ の更新 bufferBmd_.lock(); bufferBmd_.fillRect(bufferBmd_.rect, 0x00000000); var len:uint = data.length; for (var i:int = 0; i < len; i += 3) { var px:int = data[i] >> 0; var py:int = data[i + 1] >> 0; var color:int = data[i + 2] >> 0; bufferBmd_.setPixel32(px, py, color); } bufferBmd_.unlock(); // bmd_ の更新 bmd_.lock(); bmd_.colorTransform(rect_, FADE); bmd_.applyFilter(bmd_, rect_, ZERO_POINT, BLUR); bmd_.draw(bufferBmd_); bmd_.unlock(); } } //} //package { /** * 座標 * @author YOSHIDA, Akio (Aquioux) */ /*public*/ class Vertex { // X座標値 public function get x():Number { return _x; } public function set x(value:Number):void { _x = value; } private var _x:Number; // Y座標値 public function get y():Number { return _y; } public function set y(value:Number):void { _y = value; } private var _y:Number; // Z座標値 public function get z():Number { return _z; } public function set z(value:Number):void { _z = value; } private var _z:Number; // 経度上の位置 public function get longitude():int { return _longitude; } public function set longitude(value:int):void { _longitude = value; } private var _longitude:int; // 緯度上の位置 public function get latitude():int { return _latitude; } public function set latitude(value:int):void { _latitude = value; } private var _latitude:int; public function Vertex() { } } //} //package aquioux.display.colorUtil { /** * コサインカーブで色相環的な RGB を計算 * @author Aquioux(YOSHIDA, Akio) */ /*public*/ class CycleRGB { /** * 32bit カラーのためのアルファ値(0~255) */ static public function get alpha():uint { return _alpha; } static public function set alpha(value:uint):void { _alpha = (value > 0xFF) ? 0xFF : value; } private static var _alpha:uint = 0xFF; private static const PI:Number = Math.PI; // 円周率 private static const DEGREE120:Number = PI * 2 / 3; // 120度(弧度法形式) /** * 角度に応じた RGB を得る * @param angle HSV のように角度(度数法)を指定 * @return 色(0xNNNNNN) */ public static function getColor(angle:Number):uint { var radian:Number = angle * PI / 180; var r:uint = (Math.cos(radian) + 1) * 0xFF >> 1; var g:uint = (Math.cos(radian + DEGREE120) + 1) * 0xFF >> 1; var b:uint = (Math.cos(radian - DEGREE120) + 1) * 0xFF >> 1; return r << 16 | g << 8 | b; } /** * 角度に応じた RGB を得る(32bit カラー) * @param angle HSV のように角度(度数法)を指定 * @return 色(0xNNNNNNNN) */ public static function getColor32(angle:Number):uint { return _alpha << 24 | getColor(angle); } } //} Code Fullscreen Preview Fullscreen BeloitAve dentaq ProjectNya clockmaker Nyarineko ThatsAsif yuugurenote MaxWei snowsunny djankey taomengyu siouxcitizen.. brad426 shihu atakanckilic.. bradsedito mousepancyo okoi alwAYs Linkforce novita001 korooooon : 光 hidrodixtion.. : awesomemathvisualizer Particle awesome math visualizer 光 alpha fixed mouseY mouseX target Math.cos sortOn clone Array.NUMERIC MouseEvent buttonMode BlurFilter Vector MouseEvent.MOUSE_MOVE Math.sin MouseEvent.MOUSE_UP MouseEvent.MOUSE_DOWN MouseEvent.ENTER_FRAME Math.PI addChild sort new page view favorite forked pv120 forked from: Neon Sphere en-kun forked:0 favorite:0lines:262 (diff:1) pv136 forked from: Neon Sphere koori.m forked:0 favorite:1lines:262 (diff:1) pv107 forked from: Neon Sphere koori.m forked:0 favorite:0lines:262 (diff:2) pv433 forked from: Neon Sphere grp223 forked:0 favorite:0lines:262 (diff:2) pv235 forked from: Neon Sphere bradsedito forked:0 favorite:0lines:263 (diff:9)