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

ビット論理演算子によるパターン描画(1)

/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3KxH
 */

package {
    //import aquioux.display.colorUtil.CycleRGB;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    [SWF(width = "465", height = "465", frameRate = "30", backgroundColor = "#000000")]
    /**
     * ビット論理演算子によるパターン描画(1)
     * @see    http://aquioux.net/blog/?p=1943
     * @author Aquioux(Yoshida, Akio)
     */
    public class Main1 extends Sprite {
        // ステージサイズ
        private const SW:int = stage.stageWidth;
        private const SH:int = stage.stageHeight;

        // 表示 BitmapData
        private var bmd_:BitmapData;
        // BitmapData.setVector 用
        private var colorData_:Vector.<uint>;
        // colorData_ の基
        private var degreeData_:Vector.<uint>;

        // 演算関数
        private var func_:Function;
        
        // カラーマップ
        private var colors_:Vector.<uint>
        private var colors1_:Vector.<uint>;
        private var colors2_:Vector.<uint>;
        // カラー階調数
        private const DEGREE:int = 0xFF;
        
        // ボタン
        private var calcButton1_:PushButton;
        private var calcButton2_:PushButton;
        private var calcButton3_:PushButton;
        private var colorButton1_:PushButton;
        private var colorButton2_:PushButton;
        private var prevCalcButton_:PushButton;
        private var prevColorButton_:PushButton;
        

        public function Main1():void {
            // カラーマップ
            colors_ = new Vector.<uint>(DEGREE, true);
            // カラーパターン1
            colors1_ = new Vector.<uint>(DEGREE, true);
            for (var i:int = 0; i < DEGREE; i++) colors1_[i] = i << 16 | i << 8 | i;
            // カラーパターン2
            colors2_ = new Vector.<uint>(DEGREE, true);
            var step:Number = 315 / DEGREE;
            for (i = 0; i < DEGREE; i++) colors2_[i] = CycleRGB.getColor(i * step);
            
            // data_ 生成
            degreeData_ = new Vector.<uint>(SW * SH, true);
            colorData_  = new Vector.<uint>(SW * SH, true);

            // 表示 BitmapData 生成
            bmd_ = new BitmapData(SW, SH, false);
            addChild(new Bitmap(bmd_));
            
            // ボタン
            var buttonWidth:int  = 50;
            var buttonHeight:int = 20;
            calcButton1_  = new PushButton(this, buttonWidth * 0, buttonHeight * 0, "x | y", calcButtonHandler1);
            calcButton2_  = new PushButton(this, buttonWidth * 1, buttonHeight * 0, "x & y", calcButtonHandler2);
            calcButton3_  = new PushButton(this, buttonWidth * 2, buttonHeight * 0, "x ^ y", calcButtonHandler3);
            colorButton1_ = new PushButton(this, buttonWidth * 0, buttonHeight * 1, "gray",  colorButtonHandler1);
            colorButton2_ = new PushButton(this, buttonWidth * 1, buttonHeight * 1, "color", colorButtonHandler2);
            calcButton1_.width   = buttonWidth;
            calcButton2_.width   = buttonWidth;
            calcButton3_.width   = buttonWidth;
            colorButton1_.width  = buttonWidth;
            colorButton2_.width  = buttonWidth;
            calcButton1_.height  = buttonHeight;
            calcButton2_.height  = buttonHeight;
            calcButton3_.height  = buttonHeight;
            colorButton1_.height = buttonHeight;
            colorButton2_.height = buttonHeight;
            
            // 初期表示(演算)
            func_ = calculateOR;
            calcButton1_.enabled = false;
            prevCalcButton_ = calcButton1_;
            calcurate();

            // 初期表示(色)
            colors_ = colors1_;
            colorButton1_.enabled = false;
            prevColorButton_ = colorButton1_;
            draw();
        }
        
        
        // ボタンハンドラ
        private function calcButtonHandler1(e:Event):void {
            changeCalcButton(calcButton1_);
            func_ = calculateOR;
            calcurate();
            draw();
        }
        private function calcButtonHandler2(e:Event):void {
            changeCalcButton(calcButton2_);
            func_ = calculateAND;
            calcurate();
            draw();
        }
        private function calcButtonHandler3(e:Event):void {
            changeCalcButton(calcButton3_);
            func_ = calculateXOR;
            calcurate();
            draw();
        }
        private function colorButtonHandler1(e:Event):void {
            changeColorButton(colorButton1_);
            colors_ = colors1_;
            draw();
        }
        private function colorButtonHandler2(e:Event):void {
            changeColorButton(colorButton2_);
            colors_ = colors2_;
            draw();
        }
        // ボタン切り替え
        private function changeCalcButton(button:PushButton):void {
            button.enabled = false;
            prevCalcButton_.enabled = true;
            prevCalcButton_ = button;
        }
        private function changeColorButton(button:PushButton):void {
            button.enabled = false;
            prevColorButton_.enabled = true;
            prevColorButton_ = button;
        }
        
        // ビット論理演算実行
        private function calcurate():void {
            var idx:int = 0;
            // ステージ走査
            for (var y:int = 0; y < SH; y++) {
                for (var x:int = 0; x < SW; x++) {
                    // ビット論理演算
                    var r:int = func_(x, y);
                    // DEGREE による剰余値をカラーインデックスに割り当て
                    r %= DEGREE;
                    // 結果格納
                    degreeData_[idx++] = r;
                }
            }
        }
        // ビット論理演算
        private function calculateOR(x:int, y:int):int {
            return x | y;
        }
        private function calculateAND(x:int, y:int):int {
            return x & y;
        }
        private function calculateXOR(x:int, y:int):int {
            return x ^ y;
        }

        // 表示
        private function draw():void {
            var len:int = degreeData_.length;
            for (var i:int = 0; i < len; i++) {
                var r:int = degreeData_[i];
                colorData_[i] = colors_[r];
            }
            // 描画
            bmd_.setVector(bmd_.rect, colorData_);
        }
    }
}


//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);
        }
    }
//}