2013-10-18 6 views
6

以下に示すように、私は、長方形の画像で、プログラムで虹のスペクトルの近似値を生成する必要があります。虹のスペクトルをレンダリングするには?

rainbow spectrum

私はピックスマップを描画する方法を知って、私が探している方法です色の値を生成する。

+2

QTあなたは色相を設定することができますし、これを見てください –

+0

それからRGBを得ることができますQColorクラスがあります。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。その論文への参照をありがとう。色を正しくレンダリングすることが私が読んだ最も明快で有用な説明の1つです。 –

+0

私はあなたの答えを受け入れる。どうもありがとうございます! – MelMed