How do I draw a rainbow in Freeglut?
我正在尝试在openGL中绘制彩虹色的情节图例。这是到目前为止我得到的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | glBegin(GL_QUADS); for (int i = 0; i != legendElements; ++i) { GLfloat const cellColorIntensity = (GLfloat) i / (GLfloat) legendElements; OpenGL::pSetHSV(cellColorIntensity*360.0f, 1.0f, 1.0f); // draw the ith legend element GLdouble const xLeft = xBeginRight - legendWidth; GLdouble const xRight = xBeginRight; GLdouble const yBottom = (GLdouble)i * legendHeight / (GLdouble)legendElements + legendHeight; GLdouble const yTop = yBottom + legendHeight; glVertex2d(xLeft, yTop); // top-left glVertex2d(xRight, yTop); // top-right glVertex2d(xRight, yBottom); // bottom-right glVertex2d(xLeft, yBottom); // bottom-left } glEnd(); |
函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | void pSetHSV(float h, float s, float v) { // H [0, 360] S and V [0.0, 1.0]. int i = (int)floor(h / 60.0f) % 6; float f = h / 60.0f - floor(h / 60.0f); float p = v * (float)(1 - s); float q = v * (float)(1 - s * f); float t = v * (float)(1 - (1 - f) * s); switch (i) { case 0: glColor3f(v, t, p); break; case 1: glColor3f(q, v, p); break; case 2: glColor3f(p, v, t); break; case 3: glColor3f(p, q, v); break; case 4: glColor3f(t, p, v); break; case 5: glColor3f(v, p, q); } } |
我从http://forum.openframeworks.cc/t/hsv-color-setting/770
获得了该功能
但是,当我绘制此图形时,它看起来像这样:
我想要的是红色,绿色,蓝色,靛蓝,紫罗兰色的光谱(所以我想通过色相线性地进行迭代。但是,这似乎并不是正在发生的事情。
我不太了解
编辑:这是固定的版本,受到Jongware的启发(矩形的绘制不正确):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // draw legend elements glBegin(GL_QUADS); for (int i = 0; i != legendElements; ++i) { GLfloat const cellColorIntensity = (GLfloat) i / (GLfloat) legendElements; OpenGL::pSetHSV(cellColorIntensity * 360.0f, 1.0f, 1.0f); // draw the ith legend element GLdouble const xLeft = xBeginRight - legendWidth; GLdouble const xRight = xBeginRight; GLdouble const yBottom = (GLdouble)i * legendHeight / (GLdouble)legendElements + legendHeight + yBeginBottom; GLdouble const yTop = yBottom + legendHeight / legendElements; glVertex2d(xLeft, yTop); // top-left glVertex2d(xRight, yTop); // top-right glVertex2d(xRight, yBottom); // bottom-right glVertex2d(xLeft, yBottom); // bottom-left } glEnd(); |
我生成如下光谱颜色:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void spectral_color(double &r,double &g,double &b,double l) // RGB <- lambda l = < 380,780 > [nm] { if (l<380.0) r= 0.00; else if (l<400.0) r=0.05-0.05*sin(M_PI*(l-366.0)/ 33.0); else if (l<435.0) r= 0.31*sin(M_PI*(l-395.0)/ 81.0); else if (l<460.0) r= 0.31*sin(M_PI*(l-412.0)/ 48.0); else if (l<540.0) r= 0.00; else if (l<590.0) r= 0.99*sin(M_PI*(l-540.0)/104.0); else if (l<670.0) r= 1.00*sin(M_PI*(l-507.0)/182.0); else if (l<730.0) r=0.32-0.32*sin(M_PI*(l-670.0)/128.0); else r= 0.00; if (l<454.0) g= 0.00; else if (l<617.0) g= 0.78*sin(M_PI*(l-454.0)/163.0); else g= 0.00; if (l<380.0) b= 0.00; else if (l<400.0) b=0.14-0.14*sin(M_PI*(l-364.0)/ 35.0); else if (l<445.0) b= 0.96*sin(M_PI*(l-395.0)/104.0); else if (l<510.0) b= 0.96*sin(M_PI*(l-377.0)/133.0); else b= 0.00; } |
-
l 是输入波长[nm] < 380,780 > -
r,g,b 输出RGB颜色< 0,1 >
这是真实光谱颜色数据的简单粗略
也有不同的方法,例如:
线性颜色-复合渐变
- 像这样:http://www.physics.sfasu.edu/astro/color/spectra.html
- 但是输出对我来说不够好
人眼
您必须具有非常精确的
要使其更好,您必须对颜色进行标准化并添加指数灵敏度校正。这些曲线也随着世代的变化而变化,并且在世界的不同地区也不同。因此,除非您正在做一些特殊的医学/物理软件,否则不建议采用这种方法。
[edit1]这是我的新的物理上更准确的转换
我强烈建议您改用这种方法(以任何方式更准确,更好)
嗯,不是完全正确。在这里,我做了一个JavaScript示例。
钠黄色(589nm)太橙色,而Halpha红色(656nm)太棕色....
将此示例保存到HTML文件(需要jquery)并将其加载到浏览器中:
page.html?l = [纳米]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <!DOCTYPE html> <html><head> <script src='jquery.js'> /* * Return parameter value of name (case sensitive !) */ function get_value(parametername) { readvalue=(location.search ? location.search.substring(1) : false); if (readvalue) { parameter=readvalue.split('&'); for (i=0; i<parameter.length; i++) { if (parameter[i].split('=')[0] == parametername) return parameter[i].split('=')[1]; } } return false; } function spectral_color(l) // RGB <- lambda l = < 380,780 > [nm] { var M_PI=Math.PI; var r=0,g,b; if (l<380.0) r= 0.00; else if (l<400.0) r=0.05-0.05*Math.sin(M_PI*(l-366.0)/ 33.0); else if (l<435.0) r= 0.31*Math.sin(M_PI*(l-395.0)/ 81.0); else if (l<460.0) r= 0.31*Math.sin(M_PI*(l-412.0)/ 48.0); else if (l<540.0) r= 0.00; else if (l<590.0) r= 0.99*Math.sin(M_PI*(l-540.0)/104.0); else if (l<670.0) r= 1.00*Math.sin(M_PI*(l-507.0)/182.0); else if (l<730.0) r=0.32-0.32*Math.sin(M_PI*(l-670.0)/128.0); else r= 0.00; if (l<454.0) g= 0.00; else if (l<617.0) g= 0.78*Math.sin(M_PI*(l-454.0)/163.0); else g= 0.00; if (l<380.0) b= 0.00; else if (l<400.0) b=0.14-0.14*Math.sin(M_PI*(l-364.0)/ 35.0); else if (l<445.0) b= 0.96*Math.sin(M_PI*(l-395.0)/104.0); else if (l<510.0) b= 0.96*Math.sin(M_PI*(l-377.0)/133.0); else b= 0.00; var rgb = Math.floor(r*256)*65536+Math.floor(g*256)*256 + Math.floor(b*256); rgb = '000000' + rgb.toString(16); rgb = '#' + rgb.substr(-6).toUpperCase(); $('#color').html([r,g,b,rgb,l]); $('body').css('background-color', rgb); } </head><body> spectral_color(get_value('l')); </body> </html> |