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

放大Mandelbrot在Java中设置分形

笪涛
2023-03-14

我开始制作一个mandelbrot集分形查看器。在放大分形时,我遇到了很多问题。如果您尝试缩放,查看器将刚好靠近中心。我已经尽我所能去理解这个困境。我怎样才能放大我的分形,当我放大时,它会放大屏幕的中心,而不是分形的中心?

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



public class Mandelbrot extends JFrame implements ActionListener {

    private JPanel ctrlPanel;
    private JPanel btnPanel;
    private int numIter = 50;
    private double zoom = 130;
    private double zoomIncrease = 100;
    private int colorIter = 20;
    private BufferedImage I;
    private double zx, zy, cx, cy, temp;
    private int xMove, yMove = 0;
    private JButton[] ctrlBtns = new JButton[9];
    private Color themeColor = new Color(150,180,200);

    public Mandelbrot() {
        super("Mandelbrot Set");
        setBounds(100, 100, 800, 600);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        plotPoints();

        Container contentPane = getContentPane();

        contentPane.setLayout(null);




        ctrlPanel = new JPanel();
        ctrlPanel.setBounds(600,0,200,600);
        ctrlPanel.setBackground(themeColor);
        ctrlPanel.setLayout(null);

        btnPanel = new JPanel();
        btnPanel.setBounds(0,200,200,200);
        btnPanel.setLayout(new GridLayout(3,3));
        btnPanel.setBackground(themeColor);

        ctrlBtns[1] = new JButton("up");
        ctrlBtns[7] = new JButton("down");
        ctrlBtns[3] = new JButton ("left");
        ctrlBtns[5] = new JButton("right");
        ctrlBtns[2] = new JButton("+");
        ctrlBtns[0] = new JButton("-");
        ctrlBtns[8] = new JButton(">");
        ctrlBtns[6] = new JButton("<");
        ctrlBtns[4] = new JButton();

        contentPane.add(ctrlPanel);
        contentPane.add(new imgPanel());
        ctrlPanel.add(btnPanel);

        for (int x = 0; x<ctrlBtns.length;x++){
            btnPanel.add(ctrlBtns[x]);
            ctrlBtns[x].addActionListener(this);
        }

        validate();

    }

    public class imgPanel extends JPanel{
        public imgPanel(){
            setBounds(0,0,600,600);

        }

        @Override
        public void paint (Graphics g){
            super.paint(g);
            g.drawImage(I, 0, 0, this);
        }
    }

    public void plotPoints(){
        I = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
        for (int y = 0; y < getHeight(); y++) {
            for (int x = 0; x < getWidth(); x++) {
                zx = zy = 0;
                cx = (x - 320+xMove) / zoom;
                cy = (y - 290+yMove) / zoom;
                int iter = numIter;
                while (zx * zx + zy * zy < 4 && iter > 0) {
                    temp = zx * zx - zy * zy + cx;
                    zy = 2 * zx * zy + cy;
                    zx = temp;
                    iter--;
                }
                I.setRGB(x, y, iter | (iter << colorIter));
            }
        }
    }

    public void actionPerformed(ActionEvent ae){
        String event = ae.getActionCommand();

        switch (event){
        case "up":
            yMove-=100;
            break;
        case "down":
            yMove+=100;
            break;
        case "left":
            xMove-=100;
            break;
        case "right":
            xMove+=100;
            break;
        case "+":
            zoom+=zoomIncrease;
            zoomIncrease+=100;
            break;
        case "-":
            zoom-=zoomIncrease;
            zoomIncrease-=100;
            break;
        case ">":
            colorIter++;
            break;
        case "<":
            colorIter--;
            break;
        }



        plotPoints();
        validate();
        repaint();
    }




    public static void main(String[] args) {
        new Mandelbrot().setVisible(true);
    }
}

共有2个答案

谭宏盛
2023-03-14

我可以通过每次放大时进行额外的水平或垂直移动来解决这个问题。

因此,与其:

case "+": //zooming in
zoom+=zoomIncrease;
zoomIncrease+=100;
break;

我现在将拥有

case "+":
initialZoom = zoom;
zoom+=zoomIncrease;
zoomIncrease*=2;
xMove*=2;
yMove*=2;
break;

这基本上通过将其在x轴和y轴上的移动乘以缩放增加的因子(即2)来重新定位已绘制的图像。

盖昀
2023-03-14

Mandelbrot集存在于具有自然坐标的数学平面中。你"查看"这与BufferedImage我使用"视图端口"坐标。这一切都在这些之间的映射中。您已经将视口坐标标记为x和y,将Mandelbrot空间中的“真实”坐标标记为cx和cy。以下是公式:

        cx = (x - 320+xMove) / zoom;
        cy = (y - 290+yMove) / zoom;

为了放大和缩小一个特定的“真实”点,你希望你的位移量在你放大的时候是恒定的。问题是,位移量正在按缩放量缩放。记住cx和cy是Mandelbrot平面上的真实坐标

我猜你想要这样的东西:

    cx = ((x - 320) / zoom) + xMove;
    cy = ((y - 290) / zoom) + yMove;

这将使Mandelbrot平面中的“移动”与缩放量保持独立。我假设320和290与视口大小有关,并且在视口的中间给了一个零。

你会想要xMobile的数量

 类似资料:
  • 几年前,我和哥哥为Mandelbrot集合编写了一个Java代码。昨天我想用它找到一些很酷的变焦,但当我做了更激烈的变焦时,我开始注意到一个问题(变焦值约为1E14)。看起来像素被分组在一起,有时会产生奇怪的条纹效果。 混乱的曼德布罗特·佐姆 上面是问题的图片(应该是4k)。 以下是一些其他深度较小的缩放链接(它们必须是谷歌链接,因为它们太大了):https://photos.app.goo.gl

  • 我目前正在尝试为我一直在研究的Mandelbrot Set代码实现缩放功能。这个想法是放大/缩小我左/右键单击的地方。到目前为止,每当我点击屏幕,分形确实会放大。问题是分形不是在原点呈现的——换句话说,它没有在我想要的点上放大。我希望通过这里,我可以获得代码审查和概念上的理解,了解如何放大一个点。 以下是我在使用转义算法之前如何转换像素坐标的: MandelBrot.碎片 在我的左键点击手柄上,我

  • 问题内容: 我有两个(带有),并想用第二个帧(较新的)中的数据更新第一个帧(较旧的)。 新框架可能包含旧框架中已经包含的行的最新数据。在这种情况下,旧框架中的数据应被新框架中的数据覆盖。同样,较新的框架可能比第一个框架具有更多的列/行。在这种情况下,旧帧应被新帧中的数据放大。 熊猫文档指出, “为该轴设置不存在的键时,操作可以执行放大” 和 “ DataFrame可以通过“ 但是,这似乎不起作用,

  • 生成Mandelbrot分形的方程是。问题是,在计算机程序中,C用于屏幕上的缩放/分辨率和位置。我的问题是,我怎样才能得到这样的分形: 沃尔夫拉姆 () 我的代码(来自罗塞塔代码):

  • 我在Javascript上制作了一个程序,创建了mandelbrot分形,并在html画布上绘制了它。我的渲染方法是每行迭代,从0到500像素,然后简单地循环创建500行500像素。 我的问题是,当我渲染它的时候,(用更多的放大率刷新页面),它需要很多时间。300倍的放大率大约在30秒内工作,但5000倍需要一个多小时。请帮忙。我想有非常高的放大率和图像加载迅速。 我通过一个下载的文件运行我的程序

  • 我在Python中使用PIL模块制作了一个Mandelbrot分形。现在,我想做一个放大到一点的GIF。我在网上看过其他代码,但不用说,我不明白,因为我使用的模式有点不同(我使用的是类)。 我知道要放大我需要改变比例。。。但我显然不知道如何实施它。