1

私は SFML を使用しており、RGB で値を取るカラー関数があります。例.. (255,0,0)。表示される色が色相を循環するように、ループを介してこれらの数値を循環できるようにしたいと思います...

したがって、(76,204,63) を使用している場合、関数はこれら 3 つの数値を調整します。したがって、rgb を HSV に変換して rgb を返す関数が必要です。

これについてどのように考えますか?

使用したいsfmlコードは...

_sprite.setColor(76,204,63); これにより、スプライトが色に設定されます...色相を介して色を循環させるために、これらの数値でそれがどのように行われるかを理解しようとしています。

4

3 に答える 3

2

RGB を HSLまたはHSVに変換し、色相を変更してから、結果を RGB に変換します。

于 2012-07-12T18:51:05.813 に答える
2

少しグーグルでこの答えを見つけ、SFMLを念頭に置いてコードをC++に変換しました。私はかなりひどくキャストしているので、自由に改善してください。3x3 配列を置き換えることさえ可能であるべきだと思います。

sf::Uint8 clampAndConvert(float v)
{
    if(v < 0)
        return 0;
    if( v > 255)
        return 255;
    return static_cast<sf::Uint8>(v);
}

sf::Color RGBRotate(sf::Color old, float degrees)
{
    float cosA = cos(degrees*3.14159265f/180);
    float sinA = sin(degrees*3.14159265f/180);
    float rot = 1.f/3.f * (1.0f - cosA) + sqrt(1.f/3.f) * sinA;

    float rx = old.r * (cosA + (1.0f - cosA) / 3.0f) + old.g * rot + old.b * rot;
    float gx = old.r * rot + old.g * (cosA + 1.f/3.f*(1.0f - cosA)) + old.b * rot;
    float bx = old.r * rot + old.g * rot + old.b * cosA + 1.f/3.f * (1.0f - cosA);

    return sf::Color(clampAndConvert(rx), clampAndConvert(gx), clampAndConvert(bx), old.a);
}

編集:不要なキャストを削除しました。

編集:マトリックスを取り除きました。

編集:私が気づいたように、コードは実際には期待どおりに機能しませんが、完全に機能するハードコードされたソリューションは次のとおりです。コンパクトで素敵ではありません。

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow Screen (sf::VideoMode (800, 600, 32), "Game", sf::Style::Close);
    Screen.setFramerateLimit(60);

    sf::RectangleShape rect(sf::Vector2f(350.f, 350.f));
    rect.setPosition(150, 150);

    int dr = 0;
    int dg = 0;
    int db = 0;

    sf::Uint8 r = 255, g = 0,  b = 0;

    while (Screen.isOpen())
    {
        sf::Event Event;
        while (Screen.pollEvent (Event))
        {
            if (Event.type == sf::Event::Closed)
                Screen.close();
        }

        r += dr;
        g += dg;
        b += db;

        if(r == 255 && g == 0 && b == 0)
        {
            dr = 0; dg = 1; db = 0;
        }

        if(r == 255 && g == 255 && b == 0)
        {
            dr = -1; dg = 0; db = 0;
        }

        if(r == 0 && g == 255 && b == 0)
        {
            dr = 0; dg = 0; db = 1;
        }

        if(r == 0 && g == 255 && b == 255)
        {
            dr = 0; dg = -1; db = 0;
        }

        if(r == 0 && g == 0 && b == 255)
        {
            dr = 1; dg = 0; db = 0;
        }

        if(r == 255 && g == 0 && b == 255)
        {
            dr = 0; dg = 0; db = -1;
        }

        rect.setFillColor(sf::Color(r, g, b));

        Screen.clear();
        Screen.draw(rect);
        Screen.display();
    }

    return 0;
}
于 2012-07-12T19:54:56.783 に答える
1

上記のジェリーの答えは、正しい方法の 1 つです。輝度を維持することを気にしない場合 (そうであれば、HSV も使用しないでください)、RGB カラーを R=G=B 軸に沿って単純に回転させることができます。これは単なる行列乗算であり、HLS または HSV 空間との間の変換を節約します。

于 2012-07-12T19:08:36.647 に答える