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

マンセル色立体 ワイヤーフレーム版(Munsell Color Solid)

マンセル・カラー・システムをPV3Dのワイヤーフレームで簡易的に再現してみました。
色相(h)は回転軸を中心とした360度で、回転軸に遠い方が彩度(s)が高くなり、座標が上に行くほど明度(v)が高くなります。

昨夜ボーッとしながら作ったので間違いがあったため、彩度と明度の表示を入れ替える修正をしました。(2010.09.16)
Get Adobe Flash player
by mousepancyo 16 Sep 2010
  • Related works: 1
  • Talk

    takishiki at 16 Sep 2010 05:50
    コードを拝見しましたがマンセルではないような…。
    mousepancyo at 16 Sep 2010 06:33
    すいません明度と彩度が逆でした・・・修正します。 また、実際のマンセル色立体の再現まではいきついていませんのであくまでも簡易的な表現とお考えいただければと思います。
    takishiki at 16 Sep 2010 09:49
    お返事いただきありがとうございます。 マンセル色立体を作るための前段階としてHSVで色立体を試されているということですね。 マンセル表色系は人間の見た目で並べられた表色系なので忠実なマンセル表色系の色立体を作ろうと思うとLUTを用意して値を取得するなどの方法が必要かと思います。 一般的に手に入るのはマンセル値とxy色度のLUTかと思うので、そのままだとマンセル→Yxy→XYZ→RGB系と変換する必要があるので予めマンセルとRGB系のLUTを作ると使いやすいのではないでしょうか。 HSV色空間は明度V=100%で白や鮮やかな有彩色(0xFF000や0x00FFFFなど)が出せますが、マンセルでは明度を10に近い値まで上げると白しかないなど違いがあったりで手間がかかるとは思いますが頑張ってください! 長文失礼しました><;
    mousepancyo at 16 Sep 2010 09:59
    コメントありがとうございます。 実際にマンセル表色系を忠実に再現するにはまだまだ閾が高そうなので、おっしゃるとおり、ひとまずHSVの色相・彩度・明度を利用して色立体を試してみました。 実際にマンセル値での色立体が実現したらまた発表させていただきます。 ただ・・・実現できるのはいつの日になるのかは謎ですが。w

    Tags

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

package {
    import flash.display.Sprite;
    import flash.events.Event;
        
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.objects.special.ParticleField;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.view.Viewport3D;
    
    import frocessing.color.ColorHSV;
    
    [SWF(width="465", height="465", backgroundColor="0", frameRate="30")]
    
    public class Main extends Sprite {
        private const W:int = 465
        private const H:int = 465
        
        private var _scene:Scene3D;
        private var _camera:Camera3D;
        private var _viewport:Viewport3D;
        private var _render:BasicRenderEngine;
        private var _rootNode:DisplayObject3D;
        private var _cube:Cube

        public function Main():void {
            graphics.beginFill(0)
            graphics.drawRect(0, 0, W, H)
            graphics.endFill()
            //
            init3D();
        }
        
        private function init3D():void {
            _scene = new Scene3D();
            _viewport = new Viewport3D(0, 0, true, false);
            _rootNode = new DisplayObject3D();
            _camera = new Camera3D();
            _camera.y = 5
            _camera.z = -_camera.focus * _camera.zoom/2;
            _render = new BasicRenderEngine();
            //
            addChild(_viewport);
            _scene.addChild(_rootNode);
            setObj()
            //
            _render.renderScene(_scene, _camera, _viewport);
            addEventListener(Event.ENTER_FRAME, update);        
        }
        
        private function setObj():void{
            var n:int = 0
            var i:int = 0
            while(n < 20){
                var h:Number = (360 / 20) * n
                i = 0
                while(i < 20){
                    var s:Number = Math.random() * 1
                    var v:Number = i * .05;
                    if(i%2 != 0) v += .05;
                    var rgb:int = ColorUtil.hsvToRgb(h, s, v)
                    var matList:MaterialsList = new MaterialsList({
                        front: new WireframeMaterial(rgb, 1),
                        back: new WireframeMaterial(rgb, 1, 1),
                        right: new WireframeMaterial(rgb, 1, 1),
                        left: new WireframeMaterial(rgb, 1, 1),
                        top: new WireframeMaterial(rgb, 1, 1),
                        bottom: new WireframeMaterial(rgb, 1, 1)
                    });
                    //
                    var cube:Cube = new Cube(matList, 8, 8, 8, 1, 1, 1, 0, 0)
                    cube.y = v * 160 - 80;
                    cube.x = Math.cos( h * i * Math.PI / 180 ) * s * 80;
                    cube.z = Math.sin( h * i * Math.PI / 180 ) * s * 80;
                    _rootNode.addChild(cube)
                    //
                    i++
                }
                n++
            }
        }
                                    
        private function update(e:Event):void{
          _render.renderScene(_scene, _camera, _viewport);
          _rootNode.rotationY += 0.2;
        }

    }
}


// ColorUtil
class ColorUtil {

    // HSV > RGB
    public static function hsvToRgb(h:Number, s:Number, v:Number):Number {
        var cv:Number = Math.round(v * 255);
        var r:Number = cv;
        var g:Number = cv;
        var b:Number = cv;
        if (s > 0) {
            var i:Number = Math.floor(h / 60);
            var f:Number = h / 60 - i;
            var m:Number = Math.round(v * (1 - s) * 255);
            var n:Number = Math.round(v * (1 - s * f) * 255);
            var k:Number = Math.round(v * (1 - s * (1 - f)) * 255);
            switch (i) {
                case 0 :
                    g = k;
                    b = m;
                    break;
                case 1 :
                    r = n;
                    b = m;
                    break;
                case 2 :
                    r = m;
                    b = k;
                    break;
                case 3 :
                    r = m;
                    g = n;
                    break;
                case 4 :
                    r = k;
                    g = m;
                    break;
                case 5 :
                    g = m;
                    b = n;
                    break;
            }
        }
        return r << 16 | g << 8 | b;
    }

    // RGB > HSV
    public static function colorToHsv(color:Number):Object {
        var r:Number = color >> 16;
        var g:Number = (color >> 8) & 0xFF;
        var b:Number = color & 0xFF;
        var max:Number = Math.max(r,Math.max(g,b));
        var min:Number = Math.min(r,Math.min(g,b));
        var range:Number = max - min;
        var h:Number = 0;
        var s:Number = 0;
        var v:Number = max / 255;
        if (v > 0) {
            s = range / max;
            if (s > 0) {
                var cr:Number = (max - r) / range;
                var cg:Number = (max - g) / range;
                var cb:Number = (max - b) / range;
                if (r == max) {
                    h = cb - cg;
                } else if (g == max) {
                    h = 2 + cr - cb;
                } else {
                    h = 4 + cg - cr;
                }
                h *= 60;
                if (h<0) {
                    h+=360;
                }
            }
        }
        return {h:Math.round(h * 100) * 0.01, s:Math.round(s * 100), v:Math.round(v * 100)};
    }
}