2012-07-12 93 views
1

我使用SFML,它有一個顏色函數,它採用RGB值。例子..(255,0,0)。我希望能夠通過循環循環這些數字,以便顯示的顏色通過色調循環...週期R,G,B值爲HUE?

因此,如果我正在使用(76,204,63),該功能將調整這3個數字。所以我需要將rgb轉換成HSV的功能,然後返回rgb。

任何想法,我會怎麼做呢?

的SFML代碼,我想用的是...

_sprite.setColor(76,204,63);這將把精靈設置爲一種顏色......我可能試圖弄清楚一旦這些數字完成後,通過色調循環顏色。

+0

可能重複(http://stackoverflow.com/questions/8507885/shift-hue-of-an-rgb-color) – MasterHD 2015-09-15 10:52:21

回答

1

用google搜索一下,我發現了this的答案,並將代碼轉換爲C++並記住了SFML。 我正在四處轉悠,所以隨時讓它變得更好。我想應該甚至可以取代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; 
} 
按住[Shift RGB顏色的色調]的
2

轉換RGB to HSLHSV,修改色調,然後轉換結果back to RGB

+0

容易RGB是偉大的!感謝您的鏈接! – 2012-07-12 19:40:40

1

傑瑞上面的答案是一個正確的方法。如果你不關心保持亮度(如果你這麼做 - 也不要使用HSV),你可以簡單地沿着R = G = B軸旋轉RGB顏色。這只是一個矩陣乘法,並且可以節省您從HLS或HSV空間進行的轉換。

+0

請問您可以擴展一下嗎?我不是100%確定我理解你。 – aJynks 2012-07-12 19:21:32

+0

您可以將RGB值看作由R軸,G軸和B軸定義的空間中的3D點。然後,您可以圍繞任意軸旋轉該3D點(以及任何方向的無限線,穿過原點)。有關如何進行任意旋轉的詳細信息,請參見[這裏](http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/)。最後的矩陣看起來很可怕,但一旦計算了一次正弦和餘弦,它就變得非常簡單。請記住在進行計算之前對矢量<1,1,1>進行標準化。 – user1118321 2012-07-12 19:44:24

+0

這很容易看到這是如何工作的大旋轉。假設我們以{50,100,150}開始。我們可以將它旋轉到{150,50,150},然後再旋轉到{100,150,50}。這種旋轉相當於乘以矩陣{{0,1,0},{0,0,1},{1,0,0}}。 – MSalters 2012-07-13 08:26:24