将浮点值(0.0,100.0)映射到RGB

时间:2013-08-23 13:31:49

标签: c++ c math graphics colors

我在范围(0.0,100.0)中有大约1000个浮点值,我想将这些值映射为颜色(RGB)。到目前为止我所做的是创建一个1000色(RGB)值的色彩映射,使用浮点值索引色彩图并获得RGB值。

但问题是,由于我将浮点值转换为int,然后将它们用作colormap的索引,因此我失去了精度。执行此浮动到rgb转换的最佳方法是什么?

编辑:

color color_list[100];
float float_values[1000]
for(i = 0 to 999)
{
   int colormap_idx = float_values[i];  // Note that the float is converted into an int
   color current_color = color_list[colormap_idx];
}

2 个答案:

答案 0 :(得分:2)

您可以拥有的RGB值总数为256 ^ 3。如果你可以利用所有这些,那将是很好的,但有时很难想出一个很好的直观映射。由于总共可能有256 ^ 4个浮点数(超过可能的RGB值),无论你做什么,你都会失去精确度,但你仍然可以做得比目前更好,更好。

我不确切知道你在使用预定义的颜色映射做了什么,但考虑只定义几个对应于一些中间浮点值的中间颜色并插入每个输入浮点值。在下面的代码中,fsample和csample是您的对应点。例如:

fsample[0] = 0.0   -> csample[0] = (0, 0, 0)
fsample[1] = 0.25  -> csample[1] = (0, 0, 100)
fsample[2] = 0.5   -> csample[2] = (0, 170, 170)
fsample[3] = 0.75  -> csample[3] = (170, 170, 0)
fsample[4] = 1.0   -> csample[4] = (255, 255, 255)

这将允许您使用浮动覆盖RGB空间中的更多地面,允许更高的精度转换,同时仍然为您提供一些灵活定义中间颜色的能力。这是将灰度转换为颜色的常用方法。

您可以对此代码应用一些优化和错误检查,但为了清晰起见,我将其保留为未经优化:

int N = float_values.size();
color colormap[N];
for(i = 0 to N)
{
    colormap[i] = RGBFromFloat(float_values[i], fsample, csample, num_samples);
}



color RGBFromFloat(float in, float fsample[], float csample[], num_samples)
{
    color out;

    // find the interval that the input 'in' lies in
    // this is a simple search on an ordered array...
    // consider replacing with a better algorithm for a large number of samples
    for(i = 0 to num_samples-1)
    {
        if(fsample[i] =< in && in < fsample[i+1])
        {
             out = interpolate(fsample[i], fsample[i+1], csample[i], csample[i+1], in);    
             break;
        }
    }
    return color;
}

color interpolate(float flow, float fhigh, color clow, color chigh, float in)
{
    float t = (in-flow)/(fhigh-flow);
    return clow*(1 - t) + chigh*t
}

答案 1 :(得分:1)

我不知道这是 最好的 方法(因为你没有给我们最优标准),但是如果“我正在失去精确度”你的意思是一旦转换为int,您最多只有100种不同的颜色组合,那么您可以这样做:

// this code is C99

#define MAX_FLOAT_VAL 100.0
#define N_COLORS 2000
#define N_FLOAT_SAMPLES 1000

color color_list[N_COLORS];
float float_values[N_FLOAT_SAMPLES];

// the following loop must be placed in some function
for( int i = 0; i < N_FLOAT_SAMPLES; i++ )
{
    // the following assignment will map 
    // linearly a float in the range [0 ... MAX_FLOAT_VAL]
    // into an int in the range [0 ... (N_COLORS-1)]
    int colormap_idx = (float_values[i] / MAX_FLOAT_VAL) * (N_COLORS - 1);
    color current_color = color_list[colormap_idx];
    // ... do something with current_color ...
}

当然,您仍然必须使用合适的算法在color_list中生成条目(我建议不要手动执行此操作:-)。这是一个完全不同的问题,因为它涉及更多的“自由度”,因为您尝试将1-D空间(colormap_idx的值)映射到3-D空间(所有可能的集合) RGB三元组)。

P.S:您似乎要求我提醒我需要对分形进行着色所需的计算,例如Mandelbrot集合的图形表示。

希望这有帮助。