Mandelbrot 平滑着色算法的最佳选择是什么
What would be the best choice of smooth coloring algorithm for Mandelbrot
我正在渲染一个 mandelbrot 集并且已经实现了一些平滑的着色,但是当仔细观察时,图片变得非常嘈杂。我想知道,改善我的着色以达到更好的美感的最佳方法是什么。使用直方图着色是否有助于去除粗糙的像素化区域?
Here is a render of the fractal using 10 000 iterations.
这是我现在生成和分配颜色的方式:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int black = 0;
int[] colors = new int[max]; //max is the maximum number of iterations
for (int i = 0; i<max; i++) {
colors[i] = Color.HSBtoRGB(i/256f, 1, i/(i+8f));
}
for(int i = 0; i < colors.length / 2; i++)
{
int temp = colors[i];
colors[i] = colors[colors.length - i - 1];
colors[colors.length - i - 1] = temp;
}
...
...
...
if (iterations < max) image.setRGB(col, row, colors[iterations]);
else image.setRGB(col, row, black);
}
}
//ImageIO.write(image, "png", new File("mandelbrot_seeria90"+Integer.toString(i)+".png"));
ImageIO.write(image, "png", new File("resotest.png"));
想想循环,如果一个循环结束值到达起始值,你有几个循环。
通过创建水平伽玛来测试它,例如 |||| ... |||
颜色。
类似于:
fill:
for (int i = 0; i < max; ) {
for (int h = 0; h < NH; ++h) {
float hValue = ((float)h) / NH;
for (int b = 0; b < NB; ++b) {
doublebValue = ((double)b) / NB; // 0 .. 1
bValue = Math.sin(2 * Math.PI * bValue); // -1 .. 1
bValue = (2 + bValue) / 3; // 0.33 .. 1
colors[i] = Color.HSBtoRGB(hValue, 1, (float) bValue);
++i;
if (i >= max) {
break fill;
}
}
}
}
评论太多了,但不是一个明确的答案,抱歉。
您可以轻松地在轮廓广泛分布的地方制作平滑的颜色渐变,但在 M-Set 附近("infinite" 迭代)图像变得明显混乱,相邻像素的数量非常不同的迭代,所以它看起来很嘈杂。创建缩放时,这一点更加明显,噪声区域看起来 "dance"。
我发现最好的解决方案是在这些区域使用灰度,基于 8 个相邻像素的迭代差异。假设 "infinite" 区域是黑色的,这样的灰色像素在邻居变化最大的地方是最黑的,或者一些邻居在 M-Set 上。在较浅的一侧,当有一些相同深度的邻居时,我会从它们那里获得一些色调。在没有邻居具有相同深度的中间地带,灰色阴影将基于它们的变化。
我使用了 C 和汇编程序(用于迭代)。
一个可能产生可接受结果的简单解决方案是简单地使用 2x2、3x3 或 4x4 超级采样来消除锯齿,并通过平均 4、9 块的颜色值(而不是迭代计数)来生成每个像素或 16 像素。
这种方法只是一种通用的图像渲染技术,它没有使用任何特定的 Mandelbrot 分形知识来解决问题,但您可以通过计算相邻整个像素的迭代次数并仅进行子采样步骤来优化它如果计数不完全相同。这意味着您只会在重要的地方进行操作:在 2 次迭代计数之间的边界处或在许多不同计数彼此相邻的嘈杂区域。
您可以通过生成测试图像然后在图像编辑应用程序中按比例缩小它来测试这一点(确保您已打开过滤)。如果它看起来没问题,那么您可以通过在现有的内部像素循环中添加额外的几个 for 循环来实现它,对于每个子像素,将 c 递增 1/2、1/3或像素步长的 1/4。将颜色值相加并除以适当的量。
我正在渲染一个 mandelbrot 集并且已经实现了一些平滑的着色,但是当仔细观察时,图片变得非常嘈杂。我想知道,改善我的着色以达到更好的美感的最佳方法是什么。使用直方图着色是否有助于去除粗糙的像素化区域? Here is a render of the fractal using 10 000 iterations.
这是我现在生成和分配颜色的方式:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int black = 0;
int[] colors = new int[max]; //max is the maximum number of iterations
for (int i = 0; i<max; i++) {
colors[i] = Color.HSBtoRGB(i/256f, 1, i/(i+8f));
}
for(int i = 0; i < colors.length / 2; i++)
{
int temp = colors[i];
colors[i] = colors[colors.length - i - 1];
colors[colors.length - i - 1] = temp;
}
...
...
...
if (iterations < max) image.setRGB(col, row, colors[iterations]);
else image.setRGB(col, row, black);
}
}
//ImageIO.write(image, "png", new File("mandelbrot_seeria90"+Integer.toString(i)+".png"));
ImageIO.write(image, "png", new File("resotest.png"));
想想循环,如果一个循环结束值到达起始值,你有几个循环。
通过创建水平伽玛来测试它,例如 |||| ... |||
颜色。
类似于:
fill:
for (int i = 0; i < max; ) {
for (int h = 0; h < NH; ++h) {
float hValue = ((float)h) / NH;
for (int b = 0; b < NB; ++b) {
doublebValue = ((double)b) / NB; // 0 .. 1
bValue = Math.sin(2 * Math.PI * bValue); // -1 .. 1
bValue = (2 + bValue) / 3; // 0.33 .. 1
colors[i] = Color.HSBtoRGB(hValue, 1, (float) bValue);
++i;
if (i >= max) {
break fill;
}
}
}
}
评论太多了,但不是一个明确的答案,抱歉。
您可以轻松地在轮廓广泛分布的地方制作平滑的颜色渐变,但在 M-Set 附近("infinite" 迭代)图像变得明显混乱,相邻像素的数量非常不同的迭代,所以它看起来很嘈杂。创建缩放时,这一点更加明显,噪声区域看起来 "dance"。
我发现最好的解决方案是在这些区域使用灰度,基于 8 个相邻像素的迭代差异。假设 "infinite" 区域是黑色的,这样的灰色像素在邻居变化最大的地方是最黑的,或者一些邻居在 M-Set 上。在较浅的一侧,当有一些相同深度的邻居时,我会从它们那里获得一些色调。在没有邻居具有相同深度的中间地带,灰色阴影将基于它们的变化。
我使用了 C 和汇编程序(用于迭代)。
一个可能产生可接受结果的简单解决方案是简单地使用 2x2、3x3 或 4x4 超级采样来消除锯齿,并通过平均 4、9 块的颜色值(而不是迭代计数)来生成每个像素或 16 像素。
这种方法只是一种通用的图像渲染技术,它没有使用任何特定的 Mandelbrot 分形知识来解决问题,但您可以通过计算相邻整个像素的迭代次数并仅进行子采样步骤来优化它如果计数不完全相同。这意味着您只会在重要的地方进行操作:在 2 次迭代计数之间的边界处或在许多不同计数彼此相邻的嘈杂区域。
您可以通过生成测试图像然后在图像编辑应用程序中按比例缩小它来测试这一点(确保您已打开过滤)。如果它看起来没问题,那么您可以通过在现有的内部像素循环中添加额外的几个 for 循环来实现它,对于每个子像素,将 c 递增 1/2、1/3或像素步长的 1/4。将颜色值相加并除以适当的量。