Beispiel zur Generierung von Fraktalen

Thomas Darimont

Erfahrenes Mitglied
Hallo,

hier mal ein kleines Beispiel wie man ein Fraktal mit Java erzeugen kann. In diesem Beispiel sehen wir die Visualisierung Mandelbrot-Menge:

Mehr dazu gibts hier:
http://de.wikipedia.org/wiki/Mandelbrot-Menge
http://de.wikipedia.org/wiki/Fraktal
http://de.wikipedia.org/wiki/Komplexe_Zahl

Java:
/**
 * 
 */
package de.tutorials;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

/**
 * @author Tom
 * 
 */
public class FractalGeneratorExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        BufferedImage image = new BufferedImage(440, 350, BufferedImage.TYPE_INT_RGB);
        int maxIterations = 30;
        double pixelWidth = 0.00625;
        Graphics g = image.getGraphics();
        
        double imC = -1.1;
        final Complex zero = new Complex(0,0);
        for (int y = 0; y < 350; y++) {
            double reC = -2.1;
            for (int x = 0; x < 440; x++) {
                int iterations = 0;
                Complex c = new Complex(reC,imC);
                
                Complex z = zero;
                
                for (int i = 0; i < maxIterations; i++) {
                    z = z.square().add(c);
                    if (z.dot() > 4.0) {
                        break;
                    }
                    iterations++;
                }

                if (iterations <= 30 && iterations > 25) {
                    g.setColor(Color.RED);
                } else if(iterations <= 25 && iterations > 20){
                    g.setColor(Color.BLUE);
                }else if(iterations <= 20 && iterations > 15){
                    g.setColor(Color.GREEN);
                }else if(iterations <= 15 && iterations > 10){
                    g.setColor(Color.YELLOW);
                }else if(iterations <= 10 && iterations > 5){
                    g.setColor(Color.PINK);
                }else {
                    g.setColor(Color.WHITE);
                }
                g.drawLine(x, y, x, y);

                reC += pixelWidth;
            }
            imC += pixelWidth;
        }

        ImageIO.write(image, "jpeg", new File("c:/temp/fractal.jpg"));

    }

     static class Complex {
        double real;
        double imag;

        public Complex(double imag, double real) {
            super();
            this.imag = imag;
            this.real = real;
        }

        public double getReal() {
            return real;
        }

        public double getImag() {
            return imag;
        }

        public Complex add(Complex other) {
            return new Complex(this.real + other.real, this.imag + other.imag);
        }

        public Complex minus(Complex other) {
            return new Complex(this.real - other.real, this.imag - other.imag);
        }

        public Complex mul(Complex other) {
            return new Complex(this.real * other.real - this.imag * other.imag,
                    this.real * other.imag + this.imag * other.real);
        }

        public Complex square() {
            return new Complex(this.real * this.real - this.imag * this.imag, 2
                    * this.real * this.imag);
        }
        
        /**
         * "self"-dot Product
         * @return
         */
        public double dot(){
            return this.real * this.real + this.imag * this.imag;
        }

        @Override
        public String toString() {
            return this.real + " + " + this.imag + "i";
        }
    }
}

Hier das ganze in einem JFrame:
Java:
/**
 * 
 */
package de.tutorials;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;

/**
 * @author Tom
 * 
 */
public class FractalGeneratorExample extends JFrame {

	int currentSelectionStartX;
	int currentSelectionStartY;

	int currentX;
	int currentY;

	Runnable renderLoop = new Runnable() {
		public void run() {

			double zoomFactor = 1.0;
			double dx = 1.0;
			double dy = 1.0;

			Stroke stroke = new BasicStroke(1.0F);
			

			while (true) {
				int windowWidth = getWidth();
				int windowHeight = getHeight();

				Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();
				g.clearRect(0, 0, windowWidth, windowHeight);

				int maxIterations = 30;
				double pixelWidth = 0.00625 * zoomFactor;

				double imC = -1.1 / dy;

				//final Complex zero = new Complex(0, 0);
				
				double reC = -2.1 / dx;
				
				for (int y = 0; y < windowHeight; y++) {
					reC = -2.1 / dx;
					for (int x = 0; x < windowWidth; x++) {
						
						int iterations = 0;
						
//						Complex c = new Complex(reC, imC);
//						Complex z = zero;
//						for (int i = 0; i < maxIterations; i++) {
//							z = z.square().add(c);
//							if (z.dot() > 4.0) {
//								break;
//							}
//							iterations++;
//						}
						
						double reZ = 0.0;
						double imZ = 0.0;

						for (int i = 0; i < maxIterations; i++) {

							double newReZ = reZ * reZ - imZ * imZ;
							double newImZ = 2.0 * reZ * imZ;

							reZ = newReZ;
							imZ = newImZ;
							
							reZ += reC;
							imZ += imC;

							if (reZ * reZ + imZ * imZ > 4.0) {
								break;
							}
							iterations++;
						}

						if (iterations <= 30 && iterations > 25) {
							g.setColor(Color.RED);
						} else if (iterations <= 25 && iterations > 20) {
							g.setColor(Color.BLUE);
						} else if (iterations <= 20 && iterations > 15) {
							g.setColor(Color.GREEN);
						} else if (iterations <= 15 && iterations > 10) {
							g.setColor(Color.YELLOW);
						} else {
							g.setColor(Color.PINK);

						}
						
						//System.out.printf("reZ: %s imZ: %s\n",reC,imC);
						
						g.drawLine(x, y, x, y);

						reC += pixelWidth;
					}
					imC += pixelWidth;
				}
				
				

				g.setColor(Color.BLACK);
				g.setStroke(stroke);

				double width = currentX - currentSelectionStartX;
				double height = currentY - currentSelectionStartY;

				getBufferStrategy().show();
				g.dispose();

				dx = 2.0 - width / windowWidth / zoomFactor- zoomFactor;
				dy = 2.0 - height / windowHeight / zoomFactor - zoomFactor;

				zoomFactor *= 0.978;

				try {
					TimeUnit.MILLISECONDS.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};

	public FractalGeneratorExample() {
		super("FractalGeneratorExample");
		setLocationRelativeTo(null);

		addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseDragged(MouseEvent e) {
				Point p = e.getPoint();
				currentX = p.x;
				currentY = p.y;
			}
		});

		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				Point currentPoint = e.getPoint();
				currentSelectionStartX = currentPoint.x;
				currentSelectionStartY = currentPoint.y;

				currentX = currentSelectionStartX;
				currentY = currentSelectionStartY;
			}
		});

		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(512, 384);
		setVisible(true);
		
		createBufferStrategy(2);
		Executors.newSingleThreadExecutor().execute(renderLoop);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		new FractalGeneratorExample();
	}

	static class Complex {
		double real;
		double imag;

		public Complex(double imag, double real) {
			super();
			this.imag = imag;
			this.real = real;
		}

		public double getReal() {
			return real;
		}

		public double getImag() {
			return imag;
		}

		public Complex add(Complex other) {
			return new Complex(this.real + other.real, this.imag + other.imag);
		}

		public Complex minus(Complex other) {
			return new Complex(this.real - other.real, this.imag - other.imag);
		}

		public Complex mul(Complex other) {
			return new Complex(this.real * other.real - this.imag * other.imag, this.real * other.imag + this.imag * other.real);
		}

		public Complex square() {
			return new Complex(this.real * this.real - this.imag * this.imag , 2 * this.real * this.imag);
		}

		/**
		 * "self"-dot Product
		 * 
		 * @return
		 */
		public double dot() {
			return this.real * this.real + this.imag * this.imag;
		}

		@Override
		public String toString() {
			return this.real + " + " + this.imag + "i";
		}
	}
}

Gruß Tom
 

Anhänge

  • fractal.jpg
    fractal.jpg
    17,4 KB · Aufrufe: 30

Neue Beiträge

Zurück