In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: sphere

透明な球体の頂点に、あたかも丸いシールが貼り付いているかのように見える 3D 表現
 * 2009/01/19 Stats 追加
Get Adobe Flash player
by tepe 16 Mar 2012
// forked from Aquioux's sphere
/* 透明な球体の頂点に、あたかも丸いシールが貼り付いているかのように見える 3D 表現
 * 2009/01/19 Stats 追加
 */
package {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Vector3D;
    import flash.geom.Matrix3D;
    import flash.geom.PerspectiveProjection;
    import net.hires.debug.Stats;

    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]

    public class Main extends Sprite {
                Wonderfl.capture_delay(10);

        // 3D オブジェクトのコンテナ
        private var rootNode:Sprite;
        // 頂点
        private var vctrVertics:Vector.<Vertex>;
        // プロジェクション
        private var fov:PerspectiveProjection;
        
        // 回転に関わる変数
        private var aX:Number = 0;
        private var aY:Number = 0;
        
        // 中心から頂点までの距離
        private const DIST:uint = 200;


        public function Main() {
    
            createProjection();    // プロジェクション生成
            createContainer();    // 3D コンテナ生成
            createVertics();    // 頂点生成
            
            this.addChild(new Stats());
            
                        // イベントハンドラ
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
        }


        // イベントハンドラ
        private function onEnterFrameHandler(e:Event):void {
            aX += rootNode.mouseX*0.005;
            aY -= rootNode.mouseY*0.005;

            // 変換行列生成
            var mat:Matrix3D = new Matrix3D();
            // 回転を変換行列に合成
            mat.appendRotation(aX, Vector3D.Y_AXIS);
            mat.appendRotation(aY, Vector3D.X_AXIS);

            perspective(mat, fov);    // 投影
            zsort();                // Zソート
        }
        // 投影
        private function perspective(mat:Matrix3D, fov:PerspectiveProjection):void {
            for each (var element:Vertex in vctrVertics) {
                element.render(mat, fov, DIST);
            }
        }
        // Zソート
        private function zsort():void {
            vctrVertics.sort( function(x:Vertex, y:Vertex):Number { return y.z - x.z; } );
            var len:uint = vctrVertics.length;
            var i:int = len;
            while(i--) { rootNode.setChildIndex(vctrVertics[i], len-1); }
        }


        // プロジェクション生成
        private function createProjection():void {
            fov = new PerspectiveProjection();
            fov.fieldOfView = 60;        // 視野角の設定
        }
        // 3D コンテナ生成
        private function createContainer():void{
            rootNode = new Sprite();
            rootNode.x = stage.stageWidth / 2;
            rootNode.y = stage.stageHeight / 2;
            rootNode.z = 250;
            addChild(rootNode);
        }
        // 頂点生成
        private function createVertics():void {
            var baseNum:uint = 4;
            var vNum:uint = baseNum * 2;
            var hNum:uint = baseNum * 2;
            
            // theta:シータ(θ)は緯度、phi:ファイ(φ)は経度
            var theta:Number = Math.PI / (vNum + 1);
            var phi:Number   = Math.PI * 2 / hNum;
            
            vctrVertics = new Vector.<Vertex>();
            var i:uint = 0;
            for (var v:int = 0; v < vNum ; v++) {
                for (var h:int = 0; h < hNum ; h++) {
                    var px:Number = DIST * Math.sin(theta*(v+1)) * Math.cos(phi*h);
                    var pz:Number = DIST * Math.sin(theta*(v+1)) * Math.sin(phi*h);
                    var py:Number = DIST * Math.cos(theta*(v+1));
                    var vertex:Vertex = new Vertex(px, py, pz);
                    rootNode.addChild(vertex);
                    vctrVertics.push(vertex);
                }
            }
        }
    }
}


/*
 * 頂点クラス
 */
import flash.display.Shape;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.ColorTransform;

class Vertex extends Shape {
    private var home:Vector3D = new Vector3D();    // 座標ホームポジション
    private var proj:Vector3D = new Vector3D();    // 投影座標
    
    public function Vertex(x:Number, y:Number, z:Number) {
        this.x = home.x = x;
        this.y = home.y = y;
        this.z = home.z = z;
        // 描画
        graphics.beginFill(0xffffff);
        graphics.drawRect(-25,-25,50,50);
        //graphics.drawCircle(0, 0, 20);
        graphics.endFill();
    }
    
    public function render(mat:Matrix3D, fov:PerspectiveProjection, dist:uint):void {
        // 投影座標を計算し、自分自身(表示オブジェクト)に適用する
        proj = mat.transformVector(home);
        proj.w = fov.focalLength / (fov.focalLength + proj.z);
        proj.project();
        x = proj.x;
        y = proj.y;
        z = proj.z;
        scaleX = scaleY = 1 / proj.w;
        
        // 円が球体に貼り付いているように見せるために円を歪ませる処理
        //rotation = Math.atan2(y, x) / Math.PI * 180;
        //rotationY = Math.atan2(y, x) / Math.PI * 180;
        
        //scaleX = z / dist;
        //scaleX = scaleY = z
        
        // 円に裏と表があるように見せるために色を変える処理
        var ct:ColorTransform = new ColorTransform();
        (z > 0) ? ct.color = 0xffcc00 : ct.color = 0xcc0000;
        transform.colorTransform = ct;
    }
}