2

私は自分のゲーム フレームワーク用に HSVtoRGB メソッドを作成しています。色相を通過すると、これが発生します -> http://youtu.be/ACBwR_0iMWE

これがコードです。

public static Color HSVtoRGB(float hue, float saturation, float value, float alpha)
    {
        if(hue > 1 || saturation > 1  || value > 1) throw new Exception("values cannot be more than 1!");
        if (hue < 0 || saturation < 0|| value < 0) throw new Exception("values cannot be less than 0!");

        Color output = new Color();
        if (Math.Abs(saturation) < 0.001)
        {
            output.R = (byte) (value*byte.MaxValue);
            output.G = (byte) (value*byte.MaxValue);
            output.B = (byte) (value*byte.MaxValue);
        }
        else
        {
            hue = hue/60f;
            float f = hue - (int)hue;
            float p = value*(1f - saturation);
            float q = value*(1f - saturation*f);
            float t = value*(1f - saturation*(1f - f));
            switch ((int)hue)
            {
                case (0) :
                    output = new Color(value * 255, t * 255, p * 255, alpha);
                    break;
                case (1):
                    output = new Color(q * 255, value * 255, p * 255, alpha);
                    break;
                case (2):
                    output = new Color(p * 255, value * 255, t * 255, alpha);
                    break;
                case (3):
                    output = new Color(p * 255, q * 255, value * 255, alpha);
                    break;
                case (4):
                    output = new Color(t * 255, p * 255, value * 255, alpha);
                    break;
                case (5):
                    output = new Color(value * 255, p * 255, q * 255, alpha);
                    break;
                default :
                    throw new Exception("RGB color unknown!");
            }

        }
        return output;
    }

色相に追加.001fすると、赤から黄色に変わりますが、0 にロールオーバーするまで黄色のままになります。not を使用していることに注意してMicrosoft.Xna.Framework.ColorくださいSystem.Drawing.Color

参考までに、ここにFlixel Power Toolsの HSVtoRGB メソッドを示します。これは、基本的に私がコピーしようとしているものです。

        public static function HSVtoRGB(h:Number, s:Number, v:Number, alpha:uint = 255):uint
    {
        var result:uint;

        if (s == 0.0)
        {
            result = getColor32(alpha, v * 255, v * 255, v * 255);
        }
        else
        {
            h = h / 60.0;
            var f:Number = h - int(h);
            var p:Number = v * (1.0 - s);
            var q:Number = v * (1.0 - s * f);
            var t:Number = v * (1.0 - s * (1.0 - f));

            switch (int(h))
            {
                case 0:
                    result = getColor32(alpha, v * 255, t * 255, p * 255);
                    break;

                case 1:
                    result = getColor32(alpha, q * 255, v * 255, p * 255);
                    break;

                case 2:
                    result = getColor32(alpha, p * 255, v * 255, t * 255);
                    break;

                case 3:
                    result = getColor32(alpha, p * 255, q * 255, v * 255);
                    break;

                case 4:
                    result = getColor32(alpha, t * 255, p * 255, v * 255);
                    break;

                case 5:
                    result = getColor32(alpha, v * 255, p * 255, q * 255);
                    break;

                default:
                    FlxG.log("FlxColor Error: HSVtoRGB : Unknown color");
            }
        }

        return result;
    }
4

2 に答える 2

2

あなたのコードに基づいて、独自の HSV->RGB コンバーターを作成しました...

(また、http://www.easyrgb.com/index.php?X=MATH&H=21#text21 へのリンク)

コードは次のとおりです。

    public static Color HSVtoRGB(float hue, float saturation, float value, float alpha)
    {
        while (hue > 1f) { hue -= 1f; }
        while (hue < 0f) { hue += 1f; }
        while (saturation > 1f) { saturation -= 1f; }
        while (saturation < 0f) { saturation += 1f; }
        while (value > 1f) { value -= 1f; }
        while (value < 0f) { value += 1f; }
        if (hue > 0.999f) { hue = 0.999f; }
        if (hue < 0.001f) { hue = 0.001f; }
        if (saturation > 0.999f) { saturation = 0.999f; }
        if (saturation < 0.001f) { return new Color(value * 255f, value * 255f, value * 255f); }
        if (value > 0.999f) { value = 0.999f; }
        if (value < 0.001f) { value = 0.001f; }

        float h6 = hue * 6f;
        if (h6 == 6f) { h6 = 0f; }
        int ihue = (int)(h6);
        float p = value * (1f - saturation);
        float q = value * (1f - (saturation * (h6 - (float)ihue)));
        float t = value * (1f - (saturation * (1f - (h6 - (float)ihue))));
        switch (ihue)
        {
            case 0:
                return new Color(value, t, p, alpha);
            case 1:
                return new Color(q, value, p, alpha);
            case 2:
                return new Color(p, value, t, alpha);
            case 3:
                return new Color(p, q, value, alpha);
            case 4:
                return new Color(t, p, value, alpha);
            default:
                return new Color(value, p, q, alpha);
        }
    }

それで、私はこれをレンダリングしました: スクリーンショット

注目に値するいくつかのこと:

  • new Color(...) は、0 から 255 ではなく、0 から 1 の入力を受け取ります。
  • int と float の違いを常に明確にする
  • 状況が完全ではないたびに例外をスローしないでください。可能な限り適応するようにしてください。
  • 他のプログラムからコードを借用し、完璧な数学的リファレンスもある場合... 借用したコードの前に数学サイトをコピーしてみてください - 適切な数学からどのような奇妙な状況固有の変更が行われたかを誰が知っていますか?
于 2013-06-13T23:58:14.480 に答える
2

メソッドの開始時に、色相は 0.0f .. 1.0f に制限されます。その後、60f で除算されるため、0.0f .. 1/60.0f の範囲になります。

次に、常にゼロになる (int)hue をオンにします。

スイッチの他のブランチが実行されることはないと思います。

于 2013-06-13T09:33:31.620 に答える