在维基百科的
Mandelbrot页,有Mandelbrot集合的真正美丽的生成图像.
我也刚刚实现了我自己的mandelbrot算法.给定n是用于计算每个像素的迭代次数,我将其颜色从黑色到绿色变为白色(C和Qt 5.0):
QColor mapping(Qt::white); if (n <= MAX_ITERATIONS){ double quotient = (double) n / (double) MAX_ITERATIONS; double color = _clamp(0.f,1.f,quotient); if (quotient > 0.5) { // Close to the mandelbrot set the color changes from green to white mapping.setRgbF(color,color); } else { // Far away it changes from black to green mapping.setRgbF(0.f,color,0.f); } } return mapping;
我的结果如下:
我很喜欢它,但维基百科中的图像使用哪种颜色渐变?如何用给定的n次迭代计算该梯度?
(这个问题不是smoothing.)
解决方法
梯度可能来自Ultra Fractal.它由5个控制点定义:
Position = 0.0 Color = (0,7,100) Position = 0.16 Color = (32,107,203) Position = 0.42 Color = (237,255,255) Position = 0.6425 Color = (255,170,0) Position = 0.8575 Color = (0,2,0)
其中位置在范围[0,1],颜色是从0到255的RGB.
抓住的是它不是线性渐变.点之间的插值是立方体(或类似的东西).以下图像显示了线性和Monotone cubic插值之间的差异:
正如你所看到的,立方体更平滑和“漂亮”.我使用单调三次插值来避免可能由基本立方体引起的颜色范围的“超调”.内插值的单调三次曲线始终在输入点的范围内(0-255).
我使用以下代码来计算基于迭代的颜色i:
double size = Math.Sqrt(re * re + im * im); double smoothed = Math.Log(Math.Log(size) * ONE_OVER_LOG2) * ONE_OVER_LOG2; int colorI = (int)(Math.Sqrt(i + 1 - smoothed) * gradient.Scale + gradient.Shift) % colors.Length; Color color = colors[colorI];
其中我是分歧的迭代数,re和im是发散坐标,gradient.Scale为256,gradient.Shift为0,颜色为数组,前面显示了前离散梯度.它的长度通常是2048.