Mandelbrot集
来源:互联网 发布:电脑看电视直播软件 编辑:程序博客网 时间:2024/05/22 07:47
一,先堆一下概念:
Mandelbrot集合是在复平面上组成分形的点的集合,它正是以数学家Mandelbrot命名。
Mandelbrot集合可以用复二次多项式。
从数学上来讲,Mandelbrot集合是一个复数的集合。一个给定的复数c或者属于Mandelbrot集合M,或者不属于。比如,取c = 1,那么这个序列就是(0, 1, 2, 5, 26, …),显然它的值会趋于无穷大;而如果取c = i,那么序列就是(0, i, -1+i, -i, -1+i, -i,…),它的值会一直停留在有限半径的圆盘内。
事实上,一个点属于Mandelbrot集合当且仅当它对应的序列(由上面的二项式定义)中的任何元素的模都不大于2。这里的2就是上面提到的“有限半径”。
参考:http://www.cnblogs.com/anderslly/archive/2008/10/10/mandelbrot-set-by-fsharp.html
二,曼德布罗特集合有什么实际意义?
这里就要提出分形的概念了。
数学上认为分形有以下几个特点:
1. 具有无限精细的结构;
2. 比例自相似性;
3. 一般它的分数维大于它的拓扑维数;
4. 可以由非常简单的方法定义,并由递归、迭代产生。
分形(Fractal)一词,是曼德勃罗创造出来的,其原意是不规则、支离破碎的意思,所以分形几何学是一门以非规则几何形态为研究对象的几何学。按照分形几何学的观点,一切复杂对象虽然看似杂乱无章,但他们具有相似性,简单地说,就是把复杂对象的某个局部进行放大,其形态和复杂程度与整体相似。
分形往往由递归、迭代产生,但是我们在纸上做出的图只能作有限次的递归、迭代。所以,下面的代码,绘图的核心就是一个递归。
有兴趣可以去搜索一下:麦田圈密码;谢尔宾斯基地毯;科契雪花曲线。
三,代码实现(Java版)
package Mandelbrot;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.Timer;import java.util.TimerTask;public class Mandelbrot extends JApplet {Display canvas; // Display:每个swt程序在最开始都必须创建一个Display对象。它负责swt和操作系统之间的通信。JButton stopButton, startButton; // 启动按钮被按下时计算将开始,直到它完成计算或用户按下“停止”按钮。JTextField jtfTime; //定义一个文本框public void init() { // 初始化程序通过创建 canvas and button并将它们添加到applet的内容窗格。 this.setSize(900, 600); //把窗口设置的稍微大一点好看 setBackground(Color.gray);//背景设置为灰色 canvas = new Display();//创建一个Display对象 getContentPane().add(canvas, BorderLayout.CENTER); //在窗口面板canvas上面添加控件,添加在布局的中间CENTER JPanel bottom = new JPanel(); //创建button面板 JPanel bottom_up = new JPanel(); //创建bottom_up面板 bottom.setBackground(Color.gray);//设置button背景色为灰色 startButton = new JButton("Start");//创建一个名字为startButton的按钮控件 startButton.addActionListener(canvas); //注册事件监听器,作用是将startButton的事件处理交给canvas对象去处理 bottom.add(startButton); //Jpanel类的实例化对象bottom上 添加 JButton类的实例化对象startButton;在窗口面板上添加控件 stopButton = new JButton("Stop"); stopButton.addActionListener(canvas); bottom.add(stopButton); stopButton.setEnabled(false); //stopButton初始化时候设置为不可操作 JLabel label_left = new JLabel("computation time is:"); bottom_up.add(label_left); jtfTime = new JTextField(" "); jtfTime.setEnabled(false); jtfTime.setSize(15, 15); bottom_up.add(jtfTime); JLabel label_right = new JLabel("seconds"); bottom_up.add(label_right); getContentPane().add(bottom, BorderLayout.NORTH);//在窗口面板bottom上面添加控件,添加在布局的上边NORTH。 getContentPane().add(bottom_up, BorderLayout.SOUTH);//在窗口面板bottom_up上面添加控件,添加在布局的下边SOUTH。} // end init();/*调用此方法时由系统applet将暂时或永久停止。画布停止计算线程,如果它正在运行。*/public void stop() { canvas.stopRunning();}/*下面的嵌套类代表了applet的绘图层并做所有的工作*/ class Display extends JPanel implements ActionListener, Runnable { Image OSI; // 抽象类Image是所有表示图形图像类的父类。图像保存了曼德尔勃特集合的照片。这是复制到绘图表面,如果它存在。它是由计算的线程创建的。 Graphics OSG; // Graphics类提供基本绘图方法。在Image OSI 上draw的图形上下文。 Thread runner; // 计算线程的声明 boolean running; // running的布尔类型声明 double xmin = -2.5; // The ranges of x and y coordinates that double xmax = 1; // are represented by this drawing surface double ymin = -1.25; double ymax = 1.25; //由系统调用图显示面。如果离屏图像存在,则把离屏图像复制到屏幕上。如果离屏图像不存在,它只把表面画成黑色的。 public void paintComponent(Graphics g) { if (OSI == null) { g.setColor(Color.black); //【设置前景色】的方法是属于【Graphics】的,即设置Graphics的绘图色。语法为:g.setColor(Color对象); g.fillRect(0,0,getWidth(),getHeight()); //fillRect(int x,int y,int width,int height):是【用预定的颜色填充一个矩形】,得到一个着色的矩形块。 } else { g.drawImage(OSI,0,0,null); } } //当用户单击“starting”或“ stopping”按钮时将调用此函数。它通过starting or stopping响应动画。 public void actionPerformed(ActionEvent evt) { String command = evt.getActionCommand(); //为了避免冲突,给同一个JFrame里每个按钮设置不同的ActionCommand,监听时用这个做条件区分事件,以做不同的响应。 if (command.equals("Start")) { startRunning(); time_clock(); } else if (command.equals("Stop")) stopRunning(); } void startRunning() { if (running) return; runner = new Thread(this); // 创建一个线程,该线程将在this显示类中执行run()方法。 running = true; runner.start(); } /*做一个定时器,计算绘图的时间*/ void time_clock() { Timer timer = new Timer(); timer.schedule(new MyTask(), 0, 1000); } class MyTask extends TimerTask { int i = 0; @Override public void run() { i++; String s = String.valueOf(i); jtfTime.setText(s); if( running == false) { jtfTime.setText("0 "); i = 0; } } } void stopRunning() { // 停止计算线程的方法。是通过设置变量running的值来完成的。【线程定期检查这个值】,当running为false时将终止运行。 running = false; } //算出迭代计数的值count,以便后面用。 int countIterations(double x, double y) { //曼德尔勃特集合在while循环结束前,根据迭代的数量,通过每一个点(x,y)上着色来表示。 //曼德尔勃特的集合点,实际上是,或非常接近它,计数将达到最大值80.这些点将变成紫色。所有其他颜色代表点绝对不是集合点。 int count = 0; double zx = x; double zy = y; while (count < 80 && Math.abs(x) < 100 && Math.abs(zy) < 100) { double new_zx = zx*zx - zy*zy + x; zy = 2*zx*zy + y; zx = new_zx; count++; } return count; } int i,j; // 一个正方形的中心像素需要绘画。 这些变量是设置在Display类的run()方法中,在run()方法中用于painter对象的。这同样适用于接下来的两个变量。 int size; // 要画的正方形的大小 int colorIndex; //1和80之间的数字,用于决定正方形的颜色。 Runnable painter = new Runnable() { // Runnable对象的工作是:画一个square在离屏canvas,然后复制square到屏幕上。 //当run方法被调用时候它将这样运行。square上的数据是由前面的四个变量决定的。 public void run() { int left = i - size/2; int top = j - size/2; OSG.setColor( Color.getHSBColor(colorIndex/100.0F,1F,1F) ); OSG.fillRect(left,top,size,size); paintImmediately(left,top,size,size); } }; public void run() { //这是计算线程的run方法。它在一连串增加分辨率的方式下,绘出曼德尔勃特集合。在每一次,它填充applet、给方块着色来代表了曼德尔勃特集合。squares的大小在每次通过减少一半。 startButton.setEnabled(false); // Disable "Start" button stopButton.setEnabled(true); // and enable "Stop" button // while thread is running. int width = getWidth(); // Current size of this canvas. int height = getHeight(); OSI = createImage(getWidth(),getHeight()); //getWidth、getHeight():得到当前层的宽度与高度。 // Create the off-screen image where the picture will // be stored, and fill it with black to start. OSG = OSI.getGraphics(); //可以理解为在OSI上绘画 OSG.setColor(Color.black); OSG.fillRect(0,0,width,height); for (size = 64; size >= 1 && running; size = size/2) { //外循环执行一遍,填充图像与给定大小的方块。这是给定的像素大小。注意如果running为false,则所有循环立即结束。 double dx,dy; // 实际坐标轴的方块尺寸 dx = (xmax - xmin)/width * size; dy = (ymax - ymin)/height * size; double x = xmin + dx/2; // x-坐标 of center of square. for (i = size/2; i < width+size/2 && running; i += size) { // First nested for loop draws one column of squares.第一个嵌套循环了一列的方块。 double y = ymax - dy/2; // y-坐标 of center of square for (j = size/2; j < height+size/2 && running; j += size) { //内层for循环了一个方块,通过计算迭代确定应该是什么颜色,然后调用"painter"对象画出实际的square。 colorIndex = countIterations(x,y); //调用countIterations函数 try { SwingUtilities.invokeAndWait(painter); //将对象排到事件派发线程的队列中 } catch (Exception e) { } y -= dy; } x += dx; Thread.yield(); // Give other threads a chance to run. } } running = false; // 线程即将结束,因为计算已完成或因为running已设置为false。 在前一种情况下,我们必须设置 running= false来表明线程不再运行。 startButton.setEnabled(true); // Reset states of buttons. stopButton.setEnabled(false); } // end run()} // end nested class Display} // end class Mandelbrot
- Mandelbrot集
- Mandelbrot集
- Mandelbrot集
- Julia集与Mandelbrot集
- 用Python画Mandelbrot集
- 【计算机图形学】六、Mandelbrot集
- glut示例程序Mandelbrot集
- Mandelbrot集彩色单图程序源代码
- [OpenGL]课后案例14:Mandelbrot集程序
- Mandelbrot图像
- Mandelbrot set
- 神奇的分形艺术(四):Julia集和Mandelbrot集
- unity3d shader之Julia集和Mandelbrot集绘制美丽图案
- unity3d shader之Julia集和Mandelbrot集绘制美丽图案 (二)
- Mandelbrot集的最新变化形态一览——MandelBox,Mandelbulb,Burning Ship,NebulaBrot
- 广义mandelbrot集,使用python的matplotlib绘制,支持放大缩小
- Mandelbrot集的最新变化形态一览——MandelBox,Mandelbulb,Burning Ship,NebulaBrot
- 悼念 Benoit MandelBrot
- js书籍推荐
- Windows下使用WxWidgets库时需要额外链接的Windows静态库
- D3D网格(一)
- SPring MVC 表单校验
- HDU 2156 分数矩阵
- Mandelbrot集
- 线程中的AtomicInteger和CountDownLatch
- HDU 1283最简单的计算机
- 深入理解HTTP协议
- Java 中的成员内部类
- Git把Tag推送到远程仓库
- Activity内部Handler引起内存泄露的原因分析
- stack和queue常用方法
- 分形理论