2

色を HSL から RGB に変換する際に問題があります。私は次の関数を書きました:

struct RGB {
    float r, g, b;
};
RGB hslToRgb( float hue, float saturation, float lightness ) {

    RGB rgb1, rgbResult;

    float chroma = ( 1.0 - (float) abs( 2.0 * lightness - 1.0 ) ) * saturation;
    float h1 = hue / 60.0;
    float x = chroma * ( 1.0 - (float) abs( (float) ( (int) h1 % 2 ) - 1.0 ) );

    if ( ( 0 <= h1 ) && ( h1 < 1 ) ) {

        rgb1.r = chroma;
        rgb1.g = x;
        rgb1.b = 0.0;

    } else if ( ( 1 <= h1 ) && ( h1 < 2 ) ) {

        rgb1.r = x;
        rgb1.g = chroma;
        rgb1.b = 0.0;

    } else if ( ( 2 <= h1 ) && ( h1 < 3 ) ) {

        rgb1.r = 0.0;
        rgb1.g = chroma;
        rgb1.b = x;

    } else if ( ( 3 <= h1 ) && ( h1 < 4 ) ) {

        rgb1.r = 0.0;
        rgb1.g = x;
        rgb1.b = chroma;

    } else if ( ( 4 <= h1 ) && ( h1 < 5 ) ) {

        rgb1.r = x;
        rgb1.g = 0.0;
        rgb1.b = chroma;

    } else if ( ( 5 <= h1 ) && ( h1 < 6 ) ) {

        rgb1.r = chroma;
        rgb1.g = 0;
        rgb1.b = x;

    } else {

        rgb1.r = 0.0;
        rgb1.g = 0.0;
        rgb1.b = 0.0;

    }

    float m = lightness - 0.5 * chroma;

    rgbResult.r = rgb1.r + m;
    rgbResult.g = rgb1.g + m;
    rgbResult.b = rgb1.b + m;

    return rgbResult;

}

ここにそのテストがあります:

float cHue = 0.0;
while ( cHue < 360 ) {
    RGB rgb1 = hslToRgb( (int) cHue, 1.0, 0.5 ); // max on saturation and a middle value for lightness
    printf( "r = %f, g = %f, b = %f\n", rgb1.r, rgb1.g, rgb1.b );
    cHue += 1.0;
}

しかし、この「整数」の間のすべての範囲を取得する必要がある場合、1.0 と 0.0 しか取得できません。

r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 1.000000
r = 1.000000, g = 0.000000, b = 0.000000
r = 1.000000, g = 0.000000, b = 0.000000
r = 1.000000, g = 0.000000, b = 0.000000

誰でもこのコードで私を助けることができますか? 式: http://en.wikipedia.org/wiki/HSL_and_HSV

4

4 に答える 4

4

浮動小数点モジュロfmodfを次のように使用します。

float x = chroma * ( 1.0 - (float) abs( fmodf(h1, 2.0) - 1.0 ));
于 2012-11-15T22:47:12.613 に答える
1

C++ コードでの Cスタイルのキャスト ((int)や など) の使用を停止します。浮動小数点絶対関数が必要な場合に(float)使用します。fabs複雑な数式を多くのステップに分割すると、すべてを 1 行で実行しても効率が上がりません。

1 行につき 1 回の計算を行います。わかりやすい名前を付けて、必要と思われる型の変数に結果を格納します。int明示的に丸めることになっている場合を除き、 an の使用を避けることができるかどうかを確認してください。

于 2012-11-15T22:47:10.163 に答える
0

クロマ値がずれているようです。あなたはそれを持っています

float chroma = ( 1.0 - (float) abs( 2.0 * lightness - 1.0 ) ) * saturation;

しかし、私はそうあるべきだと思います

float chroma = saturation * lightness;

ウィキペディアが言っているので、

From HSV

Given a color with hue H ∈ [0°, 360°), saturation SHSV ∈ [0, 1], and value V ∈ [0, 1],
we first find chroma:

C = V \times S_{HSV}
于 2012-11-15T22:49:05.930 に答える
-1

あなたの回線で:

float x = chroma * ( 1.0 - (float) abs( (float) ( (int) h1 % 2 ) - 1.0 ) );

(int)モジュラスに をキャストすると、float のすべての小数が削除されます。これにより、これをバイナリ関数にします。

Michael Sh が説明したような浮動小数点モジュラス関数が必要です。

于 2012-11-15T22:50:27.000 に答える