HSV実験(使い回せそうなclassにしてみた)

by esukei forked from HSV実験(コード整理中) (diff: 244)
ja.wikipedia.org/wiki/HSV色空間
♥0 | Line 197 | Modified 2009-03-13 01:02:34 | MIT License
play

ActionScript3 source code

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

// forked from esukei's HSV実験(コード整理中)
// forked from esukei's HSV実験
/**
 * Wikipediaを参考にHSVとRGBの実験をしてみる。
 * 参考 : http://ja.wikipedia.org/wiki/HSV色空間
 * 一応使い回せるようにHSVColorクラスにしてpackageから追い出してみる。
 */
package {
    
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class HSVandRGB extends Sprite {
        
        private var shapeH:TestCircle;
        private var shapeS:TestCircle;
        private var shapeV:TestCircle;
        private var shapeA:TestCircle;
        
        public function HSVandRGB() {
            
            //色相が変わる
            shapeH = new TestCircle(0,0,80);
            //彩度が変わる
            shapeS = new TestCircle(0,0,80);
            //明度が変わる
            shapeV = new TestCircle(0,0,80);
            //全部変えてみる
            shapeA = new TestCircle(0,0,80);
            
            stage.addChild(shapeH);
            stage.addChild(shapeS);
            stage.addChild(shapeV);
            stage.addChild(shapeA);
            
            shapeH.x = stage.stageWidth / 2 -100;
            shapeH.y = stage.stageHeight / 2 - 100;
            
            shapeS.x = stage.stageWidth / 2 - 100;
            shapeS.y = stage.stageHeight / 2 + 100;
            
            shapeV.x = stage.stageWidth / 2 + 100;
            shapeV.y = stage.stageHeight / 2 - 100;
            
            shapeA.x = stage.stageWidth / 2 + 100;
            shapeA.y = stage.stageHeight / 2 + 100;
            
            var tmpH:Number = 0.0;
            var tmpS:Number = 1.0;
            var tmpV:Number = 1.0;
            
            stage.addEventListener(Event.ENTER_FRAME,function(event:Event):void{
                
                tmpH = ( (tmpH+1) % 360.0 + 360.0) % 360.0;
                tmpS -= 0.002;
                tmpS = (tmpS < 0.0) ? tmpS = 1.0 : tmpS;
                tmpV -= 0.002; 
                tmpV = (tmpV < 0.0) ? tmpV = 1.0 : tmpV;
                
                shapeH.rgbColor = HSVColor.HSVtoRGB(tmpH, 1.0, 1.0);
                shapeH.draw();

                shapeS.rgbColor = HSVColor.HSVtoRGB(tmpH, tmpS, 1.0);
                shapeS.draw();

                shapeV.rgbColor = HSVColor.HSVtoRGB(tmpH, 1.0, tmpV);
                shapeV.draw();
                
                shapeA.rgbColor = HSVColor.HSVtoRGB(tmpH, tmpS, tmpV);
                shapeA.draw();
                
            });
            
        }
    }
}

/**
 * 使い回すときは
 * ↓ここから-------------------------------
 */

/**
 * HSVColorクラス
 * @author esukei 
 *
 * メソッドはstaticにしたので、
 * 使うときは、HSVColor.RGBtoHSV(hogehoge);みたいに呼ぶ。
 *
 * もっと使いやすくしたり高速化したり、いいネーミングにしてくれたらうれしいなあ。
 */
class HSVColor
{
    public function HSVColor(){}
    
    /**
     * rgbを放り込むとhsvオブジェクトを返してくれるメソッド
     * @param  rgb:uint - RGB値
     * @return hsv:Object(HSV)  - h:Number,s:Number,v:Numberを含むObject(HSV)
     */
    public static function RGBtoHSV(rgb:uint):HSV
    {
        //rgbを分解して0.0~1.0になるようにする
        var r:Number = ( (rgb & 0xFF0000) >> 16 ) / 0xFF;
        var g:Number = ( (rgb & 0x00FF00) >> 8 ) / 0xFF;
        var b:Number = ( (rgb & 0x0000FF) ) / 0xFF;
        
        //HSVオブジェクトを作る
        var hsv:HSV = new HSV();
        hsv.h = 0.0;
        hsv.s = 0.0;
        hsv.v = 0.0;
        
        //RGBの各色の最大、最小をとる
        var max:Number = Math.max(r, Math.max(g, b) );
        var min:Number = Math.min(r, Math.min(g, b) );
        
        //最大、最小によってhの求め方を変える
        switch(max)
        {
            case r:
            {
                hsv.h = 60 * (g - b) / (max - min);
                break;
            }
            case g:
            {
                hsv.h = 60 * (b - r) / (max - min) + 120;
                break;
            }
            case b:
            {
                hsv.h = 60 * (r - g) / (max - min) + 240;
                break;
            }
            default:
            {
                break;
            }
        }
        
        //sとvを求める
        hsv.s = (max - min) / max;
        hsv.v = max;
        
        return hsv;
    }
    
    /**
     * h,s,vを放り込むとrgbを返してくれるメソッド
     * @param  h:Number - 色相のディグリー値 (0.0~360.0)
     * @param  s:Number - 彩度 (0.0~1.0)
     * @param  v:Number - 明度 (0.0~1.0)
     * @return rgb:uint - RGB値
     */
    public static function HSVtoRGB(h:Number, s:Number, v:Number):uint
    {
        var tmpR:uint = 0;
        var tmpG:uint = 0;
        var tmpB:uint = 0;
            
        //0.0~360.0に丸める
        h = (h % 360.0 + 360.0) % 360.0;
        
        //0.0~1.0に丸める
        s = Math.min( Math.max(s, 0.0) , 1.0);
        v = Math.min( Math.max(v, 0.0) , 1.0);
        
        //sが0.0の時はすべての値がvに等しい
        if(s == 0.0)
        {
            tmpR = v;
            tmpG = v;
            tmpB = v;
        }
        else
        {
            var hi:uint = (h / 60) % 6;
            var f:Number = h / 60 - hi;
            var p:Number = v * (1.0 - s);
            var q:Number = v * (1.0 - f * s);
            var t:Number = v * (1.0 - (1.0 - f) * s);
            
            switch(hi)
            {
                case 0:
                {
                    tmpR = v * 255;
                    tmpG = t * 255;
                    tmpB = p * 255;
                    break;
                }
                case 1:
                {
                    tmpR = q * 255;
                    tmpG = v * 255;
                    tmpB = p * 255;
                    break;
                }
                case 2:
                {
                    tmpR = p * 255;
                    tmpG = v * 255;
                    tmpB = t * 255;
                    break;
                }
                case 3:
                {
                    tmpR = p * 255;
                    tmpG = q * 255;
                    tmpB = v * 255;
                    break;
                }
                case 4:
                {
                    tmpR = t * 255;
                    tmpG = p * 255;
                    tmpB = v * 255;
                    break;
                }
                case 5:
                {
                    tmpR = v * 255;
                    tmpG = p * 255;
                    tmpB = q * 255;
                    break;
                }
                default:
                {
                    tmpR = 0;
                    tmpG = 0;
                    tmpB = 0;
                    break;
                }
            }        
        }
        
        return tmpR << 16 | tmpG << 8 | tmpB;
    }
}

//HSV型を作っておく
//Objectってクラスにする以外に中身に型指定って出来なかったっけ?
class HSV extends Object
{
    public var h:Number;
    public var s:Number;
    public var v:Number;
    function HSV(){}
}


/**
 * ↑ここまでをpackageの外に置いとけばOK-------------------------------
 */

//色変える図形
import flash.display.Shape;

class TestCircle extends Shape
{
    
    private var _x:Number;
    private var _y:Number;
    private var _radius:Number;
    private var _rgbColor:uint;
    
    //コンストラクタ
    function TestCircle(x:Number = 0, y:Number = 0, radius:Number = 0, rgbColor:uint = 0x000000)
    {
        _x = x;
        _y = y;
        _radius = radius;
        _rgbColor = rgbColor;
        draw();
    }
    
    public function set rgbColor(color:uint):void
    {
        _rgbColor = color;
    }
    
    public function draw():void{
        graphics.clear();
        graphics.beginFill(_rgbColor, 1.0);
        graphics.drawCircle(_x,_y,_radius);
        graphics.endFill();
    }
    
}