考虑以下函数(由Paul Bourke编写 - 搜索 Colour Ramping for Data Visualisation ):
/*
Return a RGB colour value given a scalar v in the range [vmin,vmax]
In this case each colour component ranges from 0 (no contribution) to
1 (fully saturated), modifications for other ranges is trivial.
The colour is clipped at the end of the scales if v is outside
the range [vmin,vmax]
*/
typedef struct {
double r,g,b;
} COLOUR;
COLOUR GetColour(double v,double vmin,double vmax)
{
COLOUR c = {1.0,1.0,1.0}; // white
double dv;
if (v < vmin)
v = vmin;
if (v > vmax)
v = vmax;
dv = vmax - vmin;
if (v < (vmin + 0.25 * dv)) {
c.r = 0;
c.g = 4 * (v - vmin) / dv;
} else if (v < (vmin + 0.5 * dv)) {
c.r = 0;
c.b = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
} else if (v < (vmin + 0.75 * dv)) {
c.r = 4 * (v - vmin - 0.5 * dv) / dv;
c.b = 0;
} else {
c.g = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
c.b = 0;
}
return(c);
}
hue = (h+1.0)/2; // This is to make it in range [0, 1]
temp[3] = {hue+1.0/3, hue, hue-1.0/3};
if (temp[0] > 1.0)
temp[0] -= 1.0;
if (temp[2] < 0.0)
temp[2] += 1.0;
float RGB[3];
for (int i = 0; i < 3; ++i)
{
if (temp[i]*6.0 < 1.0)
RGB[i] = 6.0f*temp[i];
else if (temp[i]*2.0 < 1.0)
RGB[i] = 1;
else if (temp[i]*3.0 < 2.0)
RGB[i] = ((2.0/3.0)-temp[i])*6.0f;
else
RGB[i] = 0;
}
6 回答
我希望这是你正在寻找的:
我不确定这个刻度是否与您链接的图像100%相同但它应该看起来非常相似 .
UPDATE I 've rewritten the code according to the description of MatLab' s找到了Jet调色板here
考虑以下函数(由Paul Bourke编写 - 搜索
Colour Ramping for Data Visualisation
):在您的情况下,您可以使用它将
[-1,1]
范围内的值映射为颜色(将C代码转换为MATLAB函数很简单):这会产生以下“热到冷”颜色斜坡:
它基本上表示RGB颜色立方体的边缘从蓝色到红色(通过青色,绿色,黄色),并沿着该路径插值 .
请注意,这与MATLAB中使用的“Jet”色彩图略有不同,据我所知,它通过以下路径:
这是我在MATLAB中做的比较:
然后我们使用以下两种情
现在你可以修改上面的C代码,并使用建议的停止点来实现类似于jet colormap的东西(它们都在R,G,B通道上使用线性插值,如上图所示)...
其他答案将插值视为分段线性函数 . 通过使用夹紧三角形基函数进行插值可以简化这一过程 . 我们需要一个钳制功能,将其输入映射到闭合单位间隔:
插值的基函数:
然后颜色变成:
将其从-1绘制为1给出:
这与this answer中提供的相同 . 使用an efficient clamp implementation:
确保你的 Value t在[-1,1]中,那么喷射颜色就是:
如上面实现
clamp
的链接所示,编译器可以优化分支 . 编译器也可以使用内在函数来设置std::abs
的符号位,从而消除另一个分支 .“热到冷”
类似的处理可用于“热 - 冷”颜色映射 . 在这种情况下,基础和颜色功能是:
[-1,1]的热到冷图:
OpenGL着色器程序
消除显式分支使得该方法有效地实现为OpenGL着色器程序 . GLSL为
abs
和clamp
提供了对3D矢量进行操作的内置函数 . 矢量化颜色计算并优先选择内置函数而不是分支可以显着提高性能 . 下面是GLSL中的一个实现,它将RGB喷射颜色作为vec3
返回 . 注意,修改基函数使得t必须位于[0,1]而不是其他示例中使用的范围 .我不确定为什么这个简单的等式有这么多复杂的答案 . 基于Amro评论中上面发布的MatLab JET热 - 冷色彩图和图表(谢谢),使用高速/基本数学计算RGB值非常简单 .
我使用以下函数进行实时渲染标准化数据以显示频谱图,并且它具有令人难以置信的快速和高效,在双精度乘法和除法之外没有复杂的数学运算,通过三元逻辑链简化 . 这段代码是C#,但很容易移植到几乎任何其他语言(对不起PHP程序员,由于异常的三元链序,你运气不好) .
该函数采用每个JET颜色规范的-1.0到1.0的序数范围,但是如果你在该范围之外,那么这个函数不会进行健全性检查(我在这里之前这样做) .
因此,请确保在调用此函数之前进行完整性/边界检查,或者只是在自己实现时添加自己的限制以限制值 .
这种实现不需要考虑到光度,所以可能不会被认为是一种纯粹的实施方式,但会让你在球场上相当好并且速度更快 .
看起来你有HSL系统的色调值,并且饱和度和亮度是隐含的 . 在互联网上搜索HSL到RGB的转换,你会发现很多解释,代码等 . (这里是one link)
但是,在您的特定情况下,假设您将所有颜色饱和度默认为1,亮度为0.5 . 以下是可用于获取RGB值的公式:
想象一下,对于每个像素,您都有
h
从数据中读取的值 .并且
RGB
中的RGB值全部在[0,1]范围内 . 请注意,原始转换更复杂,我根据 saturation=1 和 lightness=0.5 的值对其进行了简化为什么这个公式?见wikipedia entry
这可能不完全相同,但可能足够接近您的需求: