2013-10-18 59 views
6

我有必要以編程方式生成一道彩虹光譜的逼近,矩形圖像中,如下圖所示:如何渲染彩虹光譜?

rainbow spectrum

我知道如何繪製的像素圖,就是我正在尋找的是如何生成顏色的值。

+2

QT擁有的QColor類,您可以設置色調,你可以得到的RGB從中 –

+0

看一看這樣的:http://qt-project.org/doc/qt -4.8/paintsystem.html,它有你需要知道的一切。一旦你完成了一些閱讀/學習,如果你陷入困境,回來後發佈一個特定的編程問題。 – JBentley

+1

你真的在問1)如何計算欄上每個位置的RGB(或HSL,HSV等)值,或者2)如何給出正確的顏色來創建欄,或者3)兩者? –

回答

14

您需要登錄到read this paper。認真。

除此之外,它可能需要的是使用QColor::fromHslF(x/*0.8, 0.95, 0.5)在HSL顏色表示中迭代色相,其中x在彩虹上從0.0變化到1.0。這在物理上並不準確,但也許它會這樣做。

否則,您需要一個稍微更復雜的代碼,它非常簡單地近似上面引用的論文。

screenshot

#include <QApplication> 
#include <QPainter> 
#include <QPixmap> 
#include <QLabel> 
#include <algorithm> 
#include <cmath> 

QColor wavelengthToColor(qreal lambda) 
{ 
    // Based on: http://www.efg2.com/Lab/ScienceAndEngineering/Spectra.htm 
    // The foregoing is based on: http://www.midnightkite.com/color.html 
    struct Color { 
     qreal c[3]; 
     QColor toColor(qreal factor) const { 
      qreal const gamma = 0.8; 
      int ci[3]; 
      for (int i = 0; i < 3; ++i) { 
       ci[i] = c[i] == 0.0 ? 0.0 : qRound(255 * pow(c[i] * factor, gamma)); 
      } 
      return QColor(ci[0], ci[1], ci[2]); 
     } 
    } color; 
    qreal factor = 0.0; 

    static qreal thresholds[] = { 380, 440, 490, 510, 580, 645, 780 }; 
    for (unsigned int i = 0; i < sizeof(thresholds)/sizeof(thresholds[0]); ++ i) { 
     using std::swap; 
     qreal t1 = thresholds[i], t2 = thresholds[i+1]; 
     if (lambda < t1 || lambda >= t2) continue; 
     if (i%2) swap(t1, t2); 
     color.c[i % 3] = (i < 5) ? (lambda - t2)/(t1-t2) : 0.0;; 
     color.c[2-i/2] = 1.0; 
     factor = 1.0; 
     break; 
    } 

    // Let the intensity fall off near the vision limits 
    if (lambda >= 380 && lambda < 420) { 
     factor = 0.3 + 0.7*(lambda-380)/(420 - 380); 
    } 
    else if (lambda >= 700 && lambda < 780) { 
     factor = 0.3 + 0.7*(780 - lambda)/(780 - 700); 
    } 
    return color.toColor(factor); 
} 

QPixmap rainbow(int w, int h) 
{ 
    QPixmap pm(w, h); 
    QPainter p(&pm); 
    qreal f1 = 1.0/400; 
    qreal f2 = 1.0/780; 
    for (int x = 0; x < w; ++ x) { 
     // Iterate across frequencies, not wavelengths 
     qreal lambda = 1.0/(f1-(x/qreal(w)*(f1-f2))); 
     p.setPen(wavelengthToColor(lambda)); 
     p.drawLine(x, 0, x, h); 
    } 
    return pm; 
} 

class RainbowLabel : public QLabel { 
protected: 
    void resizeEvent(QResizeEvent *) { 
     setPixmap(rainbow(width(), height())); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    RainbowLabel l; 
    l.resize(600, 100); 
    l.show(); 
    return a.exec(); 
} 
+0

+1。感謝您參考該論文。這是我已經閱讀過的關於正確渲染顏色的最清晰和最有用的解釋之一。 –

+0

我接受你的回答。非常感謝! – MelMed