我目前正在编写一个程序来生成真正巨大的(65536x65536像素及以上)Mandelbrot图像,我想设计一种能够正义的光谱和着色方案.在维基百科特色的Mandelbrot图像似乎是一个很好的例子,调色板尤其是如何保持在序列中的所有缩放级别变化.不过,我不确定它是在旋转调色板还是做其他一些技巧来实现这一点.
我熟悉mandelbrot集的平滑着色算法,所以我可以避免使用条带,但我仍然需要一种方法来为此算法的输出值指定颜色.
我正在生成的图像是金字塔形的(例如,一系列图像,每个图像的尺寸都是前一个图像的一半),所以我可以使用某种旋转调色板,只要调色板之间的变化即可缩放级别不是太明显.
这是平滑的颜色算法:
让我们说你从复数开始,z0
迭代n
次数直到它逃脱.让终点是zn
.
一个平滑的价值
nsmooth := n + 1 - Math.log(Math.log(zn.abs()))/Math.log(2)
这仅适用于mandelbrot,如果你想为julia集计算平滑函数,那么使用
Complex z = new Complex(x,y); double smoothcolor = Math.exp(-z.abs()); for(i=0;i然后
smoothcolor
是在间隔(0,max_iter)
.分
smoothcolor
与max_iter
得到0和1之间的一个数值.要从值中获得平滑的颜色:
这可以被调用,例如(在Java中):
Color.HSBtoRGB(0.95f + 10 * smoothcolor ,0.6f,1.0f);因为HSB颜色参数中的第一个值用于定义色环的颜色.
感谢Julia Set光滑的颜色配方,在https://www.shadertoy.com/view/XssXDr中使用它
2> Sparr..:使用平滑着色算法计算视口中的所有值,然后将调色板从最低值映射到最高值.因此,当您放大并且较高的值不再可见时,调色板也会缩小.对于n和B使用相同的常量,对于完全缩小的集合,最终会得到0.0到1.0的范围,但是在更深的缩放处,动态范围将缩小,例如在200%缩放时为0.0到0.1,0.0到0.0001 at 20000%变焦等
3> 小智..:这是一个天真的Mandelbrot发电机的典型内环.要获得平滑的颜色,您需要传递真实和复杂的"长度"以及您提供的迭代.我已经包含了Mandelbrot代码,因此您可以查看用于计算颜色的变量.
for (ix = 0; ix < panelMain.Width; ix++) { cx = cxMin + (double )ix * pixelWidth; // init this go zx = 0.0; zy = 0.0; zx2 = 0.0; zy2 = 0.0; for (i = 0; i < iterationMax && ((zx2 + zy2) < er2); i++) { zy = zx * zy * 2.0 + cy; zx = zx2 - zy2 + cx; zx2 = zx * zx; zy2 = zy * zy; } if (i == iterationMax) { // interior, part of set, black // set colour to black g.FillRectangle(sbBlack, ix, iy, 1, 1); } else { // outside, set colour proportional to time/distance it took to converge // set colour not black SolidBrush sbNeato = new SolidBrush(MapColor(i, zx2, zy2)); g.FillRectangle(sbNeato, ix, iy, 1, 1); }和MapColor如下:(请参阅此链接以获取ColorFromHSV函数)
private Color MapColor(int i, double r, double c) { double di=(double )i; double zn; double hue; zn = Math.Sqrt(r + c); hue = di + 1.0 - Math.Log(Math.Log(Math.Abs(zn))) / Math.Log(2.0); // 2 is escape radius hue = 0.95 + 20.0 * hue; // adjust to make it prettier // the hsv function expects values from 0 to 360 while (hue > 360.0) hue -= 360.0; while (hue < 0.0) hue += 360.0; return ColorFromHSV(hue, 0.8, 1.0); }MapColour正在"平滑"从0到1的救助值,然后可以用来映射颜色而不会出现可怕的条带.使用MapColour和/或hsv函数可以改变使用的颜色.