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

YIQ Color Cube

Get Adobe Flash player
by Aquioux 27 Oct 2010
    Embed
/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/A25N
 */

package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    import net.hires.debug.Stats;
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
    /**
     * YIQ Color Cube
     * @see http://wonderfl.net/c/3AnJ
     * @author Aquioux
     */
    public class Main extends Sprite {
        private var viewer_:Bitmap;            // ビューア
        private var draw_:BitmapDataDraw;    // ビューアが表示する BitmapData を生成
        private var calc_:Calculate;        // BitmapDataDraw に表示する内容を計算

        /**
         * コンストラクタ
         */ 
        public function Main() {
            setup();
            addEventListener(Event.ENTER_FRAME, update);
        }
        
        // 初期化
        private function setup():void {
            var sw:int = stage.stageWidth;
            var sh:int = stage.stageHeight;
            
            calc_ = new Calculate();
            calc_.setup(sw, sh);

            draw_ = new BitmapDataDraw();
            draw_.setup(sw, sh);

            viewer_ = new Bitmap();
            addChild(viewer_);
        }
        
        // ループ
        private function update(e:Event):void {
            calc_.update(mouseX, mouseY);
            draw_.update(calc_.data);
            viewer_.bitmapData = draw_.bitmapData;
        }
    }
}


//package {
//    import aquioux.geom.Number4;
    import flash.geom.Matrix3D;
    import flash.geom.PerspectiveProjection;
    import flash.geom.Point;
    import flash.geom.Utils3D;
    import flash.geom.Vector3D;
    /**
     * BitmapDataDraw に表示する内容を計算
     * @author Aquioux
     */
    /*public*/ class Calculate {
        /**
         * Viewer に渡す座標データ
         */
        public function get data():Vector.<Number> { return _data; }
        private var _data:Vector.<Number>;
        
        // 各座標軸のオフセット
        private var offsetX_:Number = 0.0;
        private var offsetY_:Number = 0.0;
        private var offsetZ_:Number = 75.0;
        
        // Utils3D.projectVectors 用
        private var m_:Matrix3D;
        private var verts_:Vector.<Number>;
        private var projectedVerts_:Vector.<Number>;
        private var uvts_:Vector.<Number>;
        
        // PerspectiveProjection
        private var projection_:PerspectiveProjection;
        private var projectionMatrix3D_:Matrix3D;

        // 座標移動用
        private var vx_:Number = 0.0;
        private var vy_:Number = 0.0;
        private var speed_:Number = 0.015;
        
        private var colors_:Vector.<uint>;
        

        /**
         * コンストラクタ
         */ 
        public function Calculate() {
        }
        
        /**
         * 初期化
         * @param    w    ステージ幅
         * @param    h    ステージ高
         */
        public function setup(w:Number, h:Number):void {
            offsetX_ = w / 2;
            offsetY_ = h / 2;
            
            var factory:DataFactory = new DataFactory();
            
            // Utils3D.projectVectors 用
            m_ = new Matrix3D();
            verts_ = factory.verts;
            var n:uint = factory.verts.length / 3;
            projectedVerts_ = new Vector.<Number>(n * 2, true);
            uvts_           = new Vector.<Number>(n * 3, true);
            
            colors_ = factory.colors;
            
            _data = new Vector.<Number>(n * 3, true);
            
            // PerspectiveProjection
            projection_ = new PerspectiveProjection();
            projectionMatrix3D_ = projection_.toMatrix3D();
        }
        
        /**
         * ループ
         */
        public function update(mouseX:Number, mouseY:Number):void {
            vx_ += (offsetX_ - mouseX) * speed_;
            vy_ -= (offsetY_ - mouseY) * speed_;
            
            m_.identity();
            m_.appendRotation(vy_, Vector3D.X_AXIS);
            m_.appendRotation(vx_, Vector3D.Y_AXIS);
            m_.appendTranslation(0, 0, offsetZ_);
            m_.append(projectionMatrix3D_);

            Utils3D.projectVectors(m_, verts_, projectedVerts_, uvts_);
            
            // 回転を適用した外部データを zsort
            var sort:Array = [];
            var n:uint = projectedVerts_.length / 2;
            for (var i:int = 0; i < n; i++) {
                var v:Number4 = new Number4();
                v.x = projectedVerts_[i * 2]     + offsetX_;
                v.y = projectedVerts_[i * 2 + 1] + offsetY_;
                v.z = uvts_[i * 3 + 2];
                v.w = colors_[i];
                sort.push(v);
            }
            sort.sortOn("z", Array.NUMERIC);
            
            // sort した Array から必要なデータを生成し、Vector.<Number> に代入
            var zLevel:Number = 1 / offsetZ_;
            for (i = 0; i < n; i++) {
                v = sort[i];
                _data[i * 3]     = v.x;
                _data[i * 3 + 1] = v.y;
                _data[i * 3 + 2] = v.w;
            }
        }
    }
//}


//package aquioux.geom {
    /**
     * Number 型変数を4つまとめて扱うクラス
     * 用途:ARGB形式の色、三次元座標+もうひとつの要素
     * @author YOSHIDA, Akio (Aquioux)
     */
    /*public*/ class Number4 {
        /**
         * 1つめの Number 型変数
         * ARGBカラーのおける赤
         */
        // ARGB の赤
        public function get r():Number { return _a; }
        public function set r(value:Number):void { _a = value; }
        // 三次元座標のX座標
        public function get x():Number { return _a; }
        public function set x(value:Number):void { _a = value; }
        private var _a:Number;

        /**
         * 2つめの Number 型変数
         * ARGBカラーのおける緑
         */
        // ARGB の緑
        public function get g():Number { return _b; }
        public function set g(value:Number):void { _b = value; }
        // 三次元座標のY座標
        public function get y():Number { return _b; }
        public function set y(value:Number):void { _b = value; }
        private var _b:Number;

        /**
         * 3つめの Number 型変数
         * ARGBカラーのおける青
         */
        // ARGB の青
        public function get b():Number { return _c; }
        public function set b(value:Number):void { _c = value; }
        // 三次元座標のZ座標
        public function get z():Number { return _c; }
        public function set z(value:Number):void { _c = value; }
        private var _c:Number;

        /**
         * 4つめの Number 型変数
         * ARGBカラーのおけるアルファ値
         */
        // ARGB のアルファ値
        public function get a():Number { return _d; }
        public function set a(value:Number):void { _d = value; }
        // 三次元座標と同時に管理するもうひとつの要素
        public function get w():Number { return _d; }
        public function set w(value:Number):void { _d = value; }
        private var _d:Number;
        
        /**
         * コンストラクタ
         * @param    a    1つめの変数
         * @param    b    2つめの変数
         * @param    c    3つめの変数
         * @param    d    4つめの変数
         */
        public function Number4(a:Number = 0.0, b:Number = 0.0, c:Number = 0.0, d:Number = 0.0) {
            _a = a;
            _b = b;
            _c = c;
            _d = d;
        }
        
        /**
         * 複製
         * @return    複製した Number4 インスタンス
         */
        public function clone():Number4 {
            return new Number4(_a, _b, _c, _d);
        }

        /**
         * 表示
         * @return    表示内容
         */
        public function toString():String {
            return "Number4(" + _a + ", " + _b + ", " + _c + ", " + _d + ")";
        }
    }
//}


//package {
    /*public*/ class DataFactory {
        // 外部に渡すデータ(三次元座標)
        public function get verts():Vector.<Number> { return _verts; }
        private var _verts:Vector.<Number> = new Vector.<Number>();
        
        public function get colors():Vector.<uint> { return _colors; }
        private var _colors:Vector.<uint> = new Vector.<uint>();
        
        public function DataFactory() {
            var numX:int = 14;
            var numY:int = 14;
            var numZ:int = 14;
            var intervalPosition:int = 2;
            var offsetX:Number = (numX - 1) * intervalPosition / 2;
            var offsetY:Number = (numY - 1) * intervalPosition / 2;
            var offsetZ:Number = (numZ - 1) * intervalPosition / 2;
            var intervalY:Number = 1 / (numZ - 1);
            var intervalI:Number = 2 / (numX - 1);
            var intervalQ:Number = 2 / (numY - 1);
            var offsetI:int = 1;
            var offsetQ:int = 1;
            
            for (var cz:int = 0; cz < numZ; cz++) {
                var pz:Number = cz * intervalPosition - offsetZ;
                var y:Number = intervalY * cz;
                for (var cy:int = 0; cy < numY; cy++) {
                    var py:Number = cy * intervalPosition - offsetY;
                    var q:Number = intervalQ * cy - offsetQ;
                    for (var cx:int = 0; cx < numX; cx++) {
                        var px:Number = cx * intervalPosition - offsetX;
                        _verts.push(px, py, pz);
                        var i:Number = intervalI * cx - offsetI;
                        _colors.push(yiqToRgb(y, i, q));
                    }
                }
            }
            _verts.fixed  = true;
            _colors.fixed = true;
        }

        private function yiqToRgb(y:Number, i:Number, q:Number):uint {
            // http://en.wikipedia.org/wiki/YIQ
            var r:Number = y + 0.9563 * i + 0.6210 * q;
            var g:Number = y - 0.2721 * i - 0.6474 * q;
            var b:Number = y - 1.1070 * i + 1.7046 * q;
            r *= 255;
            g *= 255;
            b *= 255;
            r >> 0;
            g >> 0;
            b >> 0;
            if (r < 0) r = 0;
            if (g < 0) g = 0;
            if (b < 0) b = 0;
            if (r > 255) r = 255;
            if (g > 255) g = 255;
            if (b > 255) b = 255;
            return r << 16 | g << 8 | b;
        }
    }
//}


//package {
    import flash.display.BitmapData;
    /**
     * ビューアが表示する BitmapData を生成
     * @author YOSHIDA, Akio (Aquioux)
     */
    /*public*/ class BitmapDataDraw {
        /**
         * View に渡す BitmapData
         */
        public function get bitmapData():BitmapData { return _bitmapData; }
        private var _bitmapData:BitmapData;
        
        /**
         * コンストラクタ
         */ 
        public function BitmapDataDraw() {
        }
        
        /**
         * 初期化
         * @param    w    ステージ幅
         * @param    h    ステージ高
         */
        public function setup(w:Number, h:Number):void {
            _bitmapData = new BitmapData(w, h, false, 0x000000);
        }
        
        /**
         * ループ
         * @param    data    描画のための座標データ(1次元 Vector)
         */
        public function update(data:Vector.<Number>):void {
            _bitmapData.lock();
            _bitmapData.fillRect(_bitmapData.rect, 0x000000);
            var len:int = data.length;
            for (var i:int = 0; i < len; i += 3) {
                _bitmapData.setPixel(data[i], data[i + 1], data[i + 2]);
            }
            _bitmapData.unlock();
        }
    }
//}