少しグーグルでこの答えを見つけ、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;
}