我目前正在研究C#中的Mandelbrot分形生成器程序。对于着色方案,我使用线性插值和数组作为查找表。
线性插值的问题是我只能使用两种颜色。
我想使用至少三种颜色,我一直在寻找双线性插值编程算法,但我找不到任何好的颜色。
我想知道你们中是否有人可以解决这个问题。
这是我的线性插值代码:
private void InitColors()
{
int range = 255;
lookup = new Color[range];
Color from = Color.White;
Color to = Color.Blue;
int red;
int green;
int blue;
for (int i = 0; i < range; i++)
{
red = ((from.R * (range - i)) + (to.R * i)) / range;
green = ((from.G * (range - i)) + (to.G * i)) / range;
blue = ((from.B * (range - i)) + (to.B * i)) / range;
lookup[i] = Color.FromArgb(red, green, blue);
}
}
编辑:也许有一个比双线性更简单的插值来获得两种以上颜色之间的渐变。只要完成工作,我真的不在乎哪种方法: - )
答案 0 :(得分:2)
你所追求的并不是真正的双线性插值。双线性意味着使用两个参数i和j在0-1范围内的二维颜色图,并使用这两个i,j值混合四种颜色 - 即
C = C_00 (1-i) (1-j) + C_10 * i * (1-j) + C_01 * (1-i) * j + C_11 * i * j
其中C_ij是角落颜色。
如果我理解你真正想要的是能够创建一个涉及多种颜色的渐变,但仍然是一维的,使用单个参数。为此,有多种方法。其中最简单的是在0-0.5范围内混合颜色A到颜色B,在0.5到1.0范围内从B到C混合。
你当然可以分成比3只更多的颜色......
执行此操作的代码如下所示:
private void InitColors( Color * colors, int n_colors)
{
int range = 255;
lookup = new Color[range];
int red;
int green;
int blue;
for (int i = 0; i < range; i++)
{
float f = float(i)/float(range);
//Work out which interval we're in
int interval = f*(n_colors);
//Special case for the end point to prevent out-of-bounds access.
if(f>=1.0) { interval = n_colors-1; }
//Work out how far into that interval we are
float ff = f * (n_colors-1) - interval;
int R = (colors[interval].R * (1-f) + colors[interval+1].R*f;
int G = (colors[interval].G * (1-f) + colors[interval+1].G*f;
int B = (colors[interval].B * (1-f) + colors[interval+1].B*f;
lookup[i] = Color.FromArgb(R, G, B);
}
}
现在有一些问题你可能不会关心,但我会提到以防万一:
这不是一个非常平滑的颜色过渡。如果你想要更平滑的行为,你需要使用基于样条的方法(从技术上讲,这是最简单的版本)。我建议考虑一下Cattmul-Rom splines。
颜色过渡不是很均匀或不错。我考虑在RGB以外的空间中进行计算,最后转换回RGB。为此,我考虑Lab
空间(HSV是另一种选择,但是你需要担心在H方向上包裹。)
希望这有帮助。
答案 1 :(得分:1)
正如您的代码中所建议的,每个颜色都可以表示为Euclidean 3空间中的矢量。
因此,给定3个任意颜色C1,C2和C3,首先找到相关的RGB矢量v1,v2,v3,然后通过采用所有“凸组合”来构造每个矢量顶端具有顶点的三角形区域。这3个载体:
c1 * v1 + c2 * v2 + c3 * v3
其中c1,c2和c3是0和1之间的标量值,c1 + c2 + c3 = 1,并且适用矢量加法(和标量乘法)的通常欧几里德规则。
注意:这也适用于任意数量的颜色。对于N种颜色,您有N个相关向量,这些向量的“凸组合”是N-1维“单形”。它是线性的,非常容易计算。但是这种方式产生的颜色梯度可能不是美学上的最佳 - 非线性方法可能会产生更美观的结果。
编辑:几何上,如果N> 1,则具有N个顶点的“单形”实际上不是N-1维。 3,因为你的“矢量”都存在于3维的RGB空间中,因此不能全部线性独立。这意味着通常(对于N> 3)在“单形”中具有不同坐标但具有相同的明显“颜色”的许多点。