当前位置: 首页 > 知识库问答 >
问题:

Mandelbrot集的可视化表示

司宏伯
2023-03-14

我想用Java生成Mandelbrot集合的PNG照片,输出应该可以在google图像搜索中轻松找到。

该集合定义为以下序列:

z_n+1 = z_n^2 + c

其中,cz是复数,z的模数总是小于2。

我首先为复数定义了一个类,该类还包含所需的基本复杂操作。

public class ComplexNumber {
    private double real;
    private double imaginary;

    public ComplexNumber(double real, double imaginary) {
        this.real = real;
        this.imaginary = imaginary;
    }

    public ComplexNumber add(ComplexNumber z1, ComplexNumber z2) {
        ComplexNumber sum = new ComplexNumber(0, 0);
        sum.real = z1.real + z2.real;
        sum.imaginary = z1.imaginary + z2.imaginary;
        return sum;
    }

    public ComplexNumber square(ComplexNumber z) {
        ComplexNumber squared = new ComplexNumber(0, 0);
        squared.real = Math.pow(z.real, 2) - Math.pow(z.imaginary, 2);
        squared.imaginary = 2 * z.real * z.imaginary;
        return squared;
    }

    public double abs() {
        double absolute = Math.sqrt(Math.pow(this.real, 2) + Math.pow(this.imaginary, 2));
        return absolute;
    }
}

然后我定义了Mandelbrot类,该类获取复数c(基于像素)的数量,使用Mandelbrot方法检查这些数字是否在Mandelbrot集中,并将该方法的输出转换为要显示的颜色。

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Mandelbrot {

    public static int mandelbrot(ComplexNumber c, ComplexNumber z, int i, int n) {
        if (i < n) {
            if (c.abs() > 2.0) {
                return i;
            } else
                return 0;
        }
        return mandelbrot(c, z.square(z).add(z, c), i, n);
    }

    // Create the Mandelbrot image, fill it and save it as PNG file.
    public static void createMandelbrotImage(int tileSize, int maxRecurse) throws IOException {
        int height = 2 * tileSize;
        int width = 3 * tileSize;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        ComplexNumber z0 = new ComplexNumber(0, 0);
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // Construct a complex number from the pixel coordinates
                float xPos = (x + 0.5f - 2 * tileSize) / tileSize;
                float yPos = (y + 0.5f - tileSize) / tileSize;
                ComplexNumber c = new ComplexNumber(xPos, yPos);

                // Check the Mandelbrot condition for this complex number
                int mb = mandelbrot(c, z0, 0, maxRecurse);

                // Translate the result to number in a reasonable range and use it as color.
                double mbl = mb > 0 ? Math.log(mb) / Math.log(maxRecurse) : 0;
                image.setRGB(x, y, (int) (mbl * 255));
            }
        }

        // Save the image as PNG
        String OS = System.getProperty("os.name").toLowerCase(); // different for win and unix
        String filePath = System.getProperty("user.dir") + (OS.indexOf("win") >= 0 ? "\\" : "/") + "mandelbrot.png";
        System.out.println("Writing mandelbrot image to: " + filePath);
        ImageIO.write(image, "png", new File(filePath));
    }

    public static void main(String[] args) throws IOException {

        createMandelbrotImage(500, 2 ^ 24);

    }
}

问题是这段代码总是输出一个黑色的空图像,我似乎没有找到错误。

共有1个答案

卜勇
2023-03-14

看起来递归mandelbrot函数的终止条件不正确。

你想让mandelbrot函数返回,当

  • z的绝对值超过2或

而且,你永远不会增加i。

因此,更新后的函数类似于:

public static int mandelbrot(ComplexNumber c, ComplexNumber z, int i, int n) {
    if (i >= n) {
        // mandelbrot function does not diverge after n iterations.
        // Returning -1 as a magic value to indicate that the point c is in the mandelbrot set.
        // Values may already be outside of the mandelbrot set in the 0th iteration, so returning -1 makes more sense.
        return -1;
    } else if (z.abs() >= 2.0) {
        // mandelbrot function is diverging after i iterations.
        return i;
    } else {
        // recursively call mandelbrot function with an updated z and an incremented i.
        return mandelbrot(c, z.squared().add(c), i + 1, n);
    }
}

最后,如果选择为mandelbrot集中的某个点返回-1,则必须更新颜色计算以将这些点设置为黑色。

int mb = mandelbrot(c, z0, 0, maxRecurse);

if (mb == -1) {
    image.setRGB(x, y, 0);
} else {
    // set the color of your image as usual
}
 类似资料:
  • 我试图在java中为Mandelbrot集编程一个可视化,有几件事我正在努力编程。我意识到围绕这个主题的问题已经被问了很多,网上有很多留档,但是很多事情看起来很复杂,我对编程相对来说是新手。 我的第一个问题是放大分形。我的目标是对分形进行“无限”缩放(当然不是无限的,只要普通计算机在计算时间和精度方面允许)。我目前采用的方法是以下计时器: 在实轴(-2,2)和虚轴(2,2)范围内使用一定次数的迭代

  • 在处理一组数据时,您通常想做的第一件事就是了解变量的分布情况。本教程的这一章将简要介绍seaborn中用于检查单变量和双变量分布的一些工具。 您可能还需要查看[categorical.html](categorical.html #categical-tutorial)章节中的函数示例,这些函数可以轻松地比较变量在其他变量级别上的分布。 import seaborn as sns import m

  • TensorFlow 图表计算强大而又复杂,图表可视化在理解和调试时显得非常有帮助。 下面是一个运作时的可式化例子。 "一个TensorFlow图表的可视化") 一个TensorFlow图表的可视化。 为了显示自己的图表,需将 TensorBoard 指向此工作的日志目录并运行,点击图表顶部窗格的标签页,然后在左上角的菜单中选择合适的运行。想要深入学习关于如何运行 TensorBoard 以及如何

  • 有一个简单的JS代码,可以呈现非常基本的Mandelbrot分形。 任务是沿其轴以随机角度旋转此分形。它不应该是画布旋转或它的图像数据,但我必须调整初始的分形公式来做到这一点。 例如,如果角度为45度或以弧度为单位的PI/4,则输出应如下所示 我试过玩没有任何成功。

  • 之前在C#上发布了一个问题。Net Mandelbrot集合,这是一个很有帮助的回答,但是我必须回到这个Mandelbrot集合,在它的双变量上实现一个结构,定义(虚坐标和实坐标)。 作为一个刚接触structs并且对structs有点生疏的人,我想就我做错了什么以及如何改进所述代码提出一些建议,因为只要看看它,我相信它可以稍微优化一下。这是使用结构的正确方法吗?如果没有,有哪些替代方案或最佳技术

  • TensorFlow 图表计算强大而又复杂,图表可视化在理解和调试时显得非常有帮助。 下面是一个运作时的可式化例子。 "一个TensorFlow图表的可视化") 一个TensorFlow图表的可视化。 为了显示自己的图表,需将 TensorBoard 指向此工作的日志目录并运行,点击图表顶部窗格的标签页,然后在左上角的菜单中选择合适的运行。想要深入学习关于如何运行 TensorBoard 以及如何