java新手上路(六):分形的艺术

1973年,坐标—法兰西学院。
人物:B.B.Mandelbrot。在合适的时间、合适的地点,Fractal一词正式登上数学界的大舞台,凭借自身独特的魅力吸引了一众狂热的数学家、物理学家,并将这场分形学科的浪潮推向了其它众多的学科。

在此以前的两千多年中,我们用经典的欧几里德几何来描述世界,使用直线,矩形等简单的几何图案去表述世界中的物体,并视之自然而然。直到二十世纪七十年代,Mandelbrot在他的问题—英国的海岸线有多长—中开始了对现实世界不规则物体的正式讨论,而分形学科也应运而生。

什么是分形,简单的说,能够称为分形的结构,一般而言都存在自身的相似性,能够在一定范围内将这种相似性无限循环得到看似复杂的图形。最后得到的图形,在总局和局部两处的空间和信息方面等特征保持相似。基于分形,我们能够描述现实生活中的树,海岸线等具有分形特征的物体。

那么分形学科的意义是什么,我们所处的世界与分形有哪些联系呢?我个人的理解是:作为这个世界的一部分和它的见证者,我们可以直观感受到得出的结论是:大自然没有常规意义上规则的物体。也就是大自然没有直线,没有矩形。这与人类社会所生产的产品有天壤之别,我们可以在某种程度上将是否具有分形的特征作为判定是自然产物或人类社会的产物。

以上便是我在初步接触分形后的总结与感受,我想,分形作为一门新兴学科,正处于飞速发展的阶段。优秀的公式,作品层出不穷。作为一个IT领域的初学者,分形的理论势必会成为IT与数学接触、结合的敲门砖。

Julia集是分形中的经典理论,在此我初步应用Julia集,在java语言中绘制对应于其的图案。
Julia集公式:f(z (n+1))=z(n)^2+c。实数和复数在一定范围内该式都成立。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;


//以Julia集为例说明分形
/*
 * 建立JuliaSet类继承JPanel作为Julia集窗口
 */
public class JuliaSet extends JPanel {
    //maxIter控制颜色的复杂程度
    private final int maxIter = 100;
    //zoom控制最后图案的放大程度
    private final double zoom = 1;
    //cX,cY对应公式中的复数c的实部和虚部
    private double cY, cX;

    //设计窗口大小和主题颜色
    public JuliaSet() {
        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.white);
    }

    //开始绘制Julia集
    void drawJuliaSet(Graphics2D g) {
        //w,h对应于窗体的宽度和高度
        int w = getWidth();
        int h = getHeight();
        BufferedImage image = new BufferedImage(w, h,
                BufferedImage.TYPE_INT_RGB);

        //给定复数c
        cX = -0.7;
        cY = 0.27015;

        //此处的moveX和moveY对应最后Julia集相对于窗口的左右平移距离
        double moveX = 0, moveY = 0;
        double zx, zy;

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                //以窗口的中心点为原点,将整个窗体视为一个长度和宽度为两个单位的坐标系开始绘图
                zx = 1.5 * (x - w / 2) / (0.5 * zoom * w) + moveX;
                zy = (y - h / 2) / (0.5 * zoom * h) + moveY;

                //以下即为公式z(n+1)=z(n)^2+c;
                float i = maxIter;
                while (zx * zx + zy * zy < 4 && i > 0) {
                    double tmp = zx * zx - zy * zy + cX;
                    zy = 2.0 * zx * zy + cY;
                    zx = tmp;
                    i--;
                }

                int c = Color.HSBtoRGB((maxIter / i) % 1, 1, i > 0 ? 1 : 0);
                image.setRGB(x, y, c);
            }
            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            g.drawImage(image, 0, 0, null);
        }

    }

    //此处为JuliaSet类的重绘方法,在这里开启画笔抗锯齿并引用  drawJuliaSet(g)开始绘制Julia集
    public void paint(Graphics gg) {
        super.paint(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        drawJuliaSet(g);
    }

    //这里实例化Julia类,并设计窗口参数。
    public static void main(String[] args) {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Julia Set");
            f.setResizable(false);
            f.add(new JuliaSet(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
    }
}

java新手上路(六):分形的艺术_第1张图片

注:代码来自于http://rosettacode.org/wiki/Rosetta_Code

你可能感兴趣的:(java新手)