gpt4 book ai didi

c++ - 如何在 Freeglut 中绘制彩虹?

转载 作者:可可西里 更新时间:2023-11-01 18:27:22 28 4
gpt4 key购买 nike

我正在尝试在 openGL 中绘制彩虹色图例。这是我到目前为止所得到的:

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();

legendElements 是构成“彩虹”的离散方 block 的数量。 xLeftxRightyBottomyTop 是构成每个平方的顶点。

函数 OpenGL::pSetHSV 如下所示:

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 得到了那个函数

但是,当我绘制它时,它看起来像这样:

enter image description here

我想要的是红色、绿色、蓝色、靛蓝、紫色的光谱(所以我想线性迭代 Hue。然而,这似乎并不是真正发生的事情.

我不太明白 pSetHSV() 中的 RGB/HSV 转换是如何工作的,所以我很难找出问题所在..

编辑:这是受 Jongware 启发的固定版本(矩形绘制不正确):

// 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();

最佳答案

我生成这样的光谱颜色:

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 >

这个简单粗暴sin真实光谱颜色数据的波近似。您还可以从中创建表格并对其进行插值或使用纹理...输出颜色为:

spectral_colors

还有不同的方法,例如:

  1. 线性颜色 - 复合渐变

  2. 人眼 X,Y,Z灵敏度曲线积分

    你必须非常精确 X,Y,Z曲线,即使是轻微的偏差也会导致“不真实”的颜色,如本例所示

    human eye XYZ sensitivity

为了让它变得更好,您必须标准化颜色并添加指数灵敏度校正。此外,这些曲线随着每一代人的变化而变化,并且在世界不同地区有所不同。所以除非你正在做一些特殊的医学/物理软件,否则走这条路不是一个好主意。

spectral colors comparison

| <- 380nm ----------------------------------------------------------------- 780nm -> |

[edit1] here 是我新的物理上更准确的转换

我强烈建议改用这种方法(它在任何方面都更准确、更好)

关于c++ - 如何在 Freeglut 中绘制彩虹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22141206/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com