在维基百科的 Mandelbrot set页面上有非常漂亮的 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, 1.f, color);
}
else {
// Far away it changes from black to green
mapping.setRgbF(0.f, color, 0.f);
}
}
return mapping;
我的结果是这样的:
我已经非常喜欢它了,但是 Wikipedia 中的图像使用哪种颜色渐变?如何用给定的 n
次迭代计算梯度?</p>
(这个问题不是关于 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)
其中 Position
在 [0, 1) 范围内,Color
是 RGB 在 [0, 255] 范围内。
问题是颜色不是线性插值的。颜色的插值可能是立方的(或类似的)。下图显示了线性和 Monotone cubic 之间的区别插值:
如您所见,三次插值会产生更平滑和“更漂亮”的渐变。我使用单调三次插值来避免三次插值可能导致的 [0, 255] 颜色范围“过冲”。单调三次确保插值始终在输入点的范围内。
我使用以下代码根据迭代计算颜色 i
:
double smoothed = Math.Log2(Math.Log2(re * re + im * im) / 2); // log_2(log_2(|p|))
int colorI = (int)(Math.Sqrt(i + 10 - smoothed) * gradient.Scale) % colors.Length;
Color color = colors[colorI];
其中i
是发散的迭代次数,re
和im
是发散的坐标,gradient.Scale
是256,并且 colors
是上面显示的具有预先计算的渐变颜色的数组。在这种情况下,它的长度是 2048。
关于c++ - 在维基百科中使用哪种颜色渐变为曼德布罗着色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16500656/