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

如何使用SWING/AWT在Java中绘制Mandelbrot集?

须景胜
2023-03-14

我试图画曼德布罗特集,其中的点是黑色的,其他的都是白色的。在这个初始版本中,我不希望能够放大,而只是创建一个静态图像。

我创建了一个ComplexNumber类,如下所示,用于处理平方运算和将复数相加。

public class ComplexNumber {

    private double real;
    private double imaginary;

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

    public ComplexNumber times(ComplexNumber number){

        double a = this.real*number.real;
        double b = this.imaginary*number.real;
        double c = this.real*number.imaginary;
        double d = this.imaginary*number.imaginary*-1;

        double newReal = a+d;
        double newImaginary = b+c;


        ComplexNumber newComplexNumber = new ComplexNumber(newReal, newImaginary);
        return newComplexNumber;
    }

    public ComplexNumber add(ComplexNumber number){

        double newReal = this.real+number.real;
        double newImaginary = this.imaginary+number.imaginary;

        return new ComplexNumber(newReal, newImaginary);

    }

    public double abs(){
        return Math.hypot(this.real, this.imaginary);
    }

    public double getReal() {
        return real;
    }

    public double getImaginary() {
        return imaginary;
    } 
}

这是我渲染GUI并实际计算Mandelbrot Set中的点的代码。

    import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

public class MandelBrotSet extends JComponent {

    public static final int WIDTH = 800;
    public static final int HEIGHT = 800;
    public static final int ITERATIONS = 100;

    public static final double startX = -2;
    public static final double width = 4;
    public static final double startY = 2;
    public static final double height = 4;

    public static final double dx = width/(WIDTH-1);
    public static final double dy = height/(HEIGHT-1);

    private BufferedImage buffer;


    public MandelBrotSet() {

        buffer = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

        JFrame frame = new JFrame("Mandelbrot Set");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(true);
        frame.getContentPane().add(this);

        frame.pack();
        frame.setVisible(true);


    }

    @Override
    public void addNotify() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
    }

    @Override
    public void paint(Graphics g) {
        g.drawImage(buffer, 0, 0, null);
    }

    public void render(){

        for (int x=0; x<WIDTH; x++){
            for (int y=0; y<HEIGHT; y++){
                int color = calculatePoint(x, y);
                buffer.setRGB(x, y, color);
            }
        }
    }



    public int calculatePoint(int x, int y){

        ComplexNumber number = convertToComplex(x, y);
        ComplexNumber z = number;
        int i;
        for (i=0; i<ITERATIONS; i++){

            z = z.times(z).add(number);

            if (z.abs()>2.0){
                break;
            }

        }

        if (i==ITERATIONS) {
            return 0x00000000;
        }
        else {
            return 0xFFFFFFFF;
        }

    }

    public static ComplexNumber convertToComplex(int x, int y){

        double real = startX + x*dx;
        double imaginary = 2 - y*dy;
        return new ComplexNumber(real, imaginary);

    }




    public static void main(String[] args) {

        MandelBrotSet mandy = new MandelBrotSet();
        mandy.render();

    }


}

运行完这段代码后,我得到了下图。看起来曼德尔布罗特的布景有一点模糊,但随后被一吨黑色遮住了。我做错了什么?

更新的解决方案如下。谢谢你的帮助。

共有1个答案

卜高超
2023-03-14

图像的渲染比显示MandelBrotSet-Object需要更长的时间,并且之后不会更新。创建一个类型为MandelBrotSet的对象,然后立即调用它的呈现方法。在创建该对象的过程中,您将它放在一个立即显示的JFrame中。当帧显示时,渲染是不完整的,这就是为什么您的ImageBuffer尚未填充(构建mandelbrot-form需要更长时间)。

要解决此问题,可以重新绘制相关组件和框架。我对awt的重绘函数的理解还不足以告诉您如何正确地进行重绘(也许其他人可以提供帮助),但将此添加到渲染方法的末尾应该会有所帮助:

revalidate();
repaint();

可以省略重新验证或重新喷漆。

如果你用完成的图像更新你的问题,会很酷:)

 类似资料:
  • 问题内容: 我正在尝试制作绘画程序的项目中。到目前为止,我已经使用Netbeans来创建GUI并设置程序。 到目前为止,我已经能够调用在其中绘制所需的所有坐标,但是我对如何在其中实际绘制感到非常困惑。 在我的代码接近尾声时,我在面板内部进行绘制的尝试失败。 谁能在这样的示例中解释/显示如何使用图形? 我发现的所有示例都创建了一个类并对其进行扩展,JPanel但是我不知道是否可以这样做,因为它是在n

  • 问题内容: 我想提请使用Java网格(10×10),但我们必须使用来实现它的,这是我的计划至今 问题答案: 该代码有效。 只需删除25

  • 问题内容: 我正在尝试制作绘画程序,但是在拖动鼠标时无法绘制线条。看来涂料一直在刷新,因此只绘制了鼠标的当前位置。我对此有些陌生,因此如何在拖动鼠标时将所有行显示在JPanel上?谢谢,这是我所拥有的: 问题答案: 有多种方法可以解决您的问题。@MattiasF和@MadProgrammer是正确的:Swing在做它应该做的事情。您的方法应该重绘整个场景,而不是添加到前一个场景。 到目前为止,建议

  • 问题内容: 我已经实现了一些带有小型图形用户界面的应用程序。没什么复杂的,但是我遇到了一些问题,这些问题导致组件无法显示或无法正常运行。 现在我的问题是: 您如何计划这些用户界面?当您需要进行更改时该怎么办?您如何调试奇怪的行为? 这几乎适用于所有类型的GUI设计。当然,使用Microsoft Visual Studio具有很大的优势,因为您几乎获得了在设计器中看到的东西。 是否存在 优秀 的AW

  • 问题内容: 我正在尝试用Java绘制曲线。一个简单的以(X,Y)开始,(X,Y)结束和曲线量的贝塞尔曲线就足够了。 我找不到在Swing中执行此操作的方法。如果不在Swing中,我可以使用一些简单的数学方法吗?我将如何在Swing中实现它? 编辑:我知道如何通过重写paint(Graphics g)方法绘制形状和线条。 问题答案: 您可以使用Java 2D Object Path2D.Double

  • 我正在编写一个Java程序来显示我的入门编程类的Mandelbrot集。我相信我已经正确地设置了所有的数学,但是当我尝试绘制分形时,我得到的只是一种纯色。我已经测试了数学,它似乎应该是有效的。我搜索了一个多小时,但没有找到任何有用的东西。下面是我的复数类,并实际创建了Mandelbrot集:复数 曼德布罗特 我已经做了一些JUnit测试,上面的两个类似乎都可以工作。我的测试中可能有一个缺陷导致了疏