You are not logged in.

  • Login

1

Friday, December 23rd 2005, 4:56pm

JAVA Mandelbrot-Menge

Die Mandelbrot-Menge, im allgemeinen Sprachgebrauch oft auch "Apfelmännchen" genannt, ist ein Fraktal, das in der Chaostheorie eine bedeutende Rolle spielt. Es wurde 1980 von Benoît Mandelbrot erstmals computergrafisch dargestellt und untersucht. Die mathematischen Grundlagen dafür wurden bereits 1905 von dem französischen Mathematiker Pierre Fatou erarbeitet.

sicherlich nützlich bei der lösung sind folgende dokumente
- http://www.thegeek.de/src/fraktal.phps
- http://www.htwm.de/~if99/grundstudium/java_pr/Praktikum14.htm
- http://www.mathematische-basteleien.de/apfelmaennchen.htm (mit weiterer literaturliste)

Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import java.io.*;
import java.io.IOException;
import java.util.Formatter;
 
/**
 * 
 * @author Torben Brodt
 * @version 1.0
 *
 * <p />Fraktale Geometrie & Komplexe Zahlen: Mandelbrot
 */
public class A1_Mandelbrot {
 
    /**
     * @param args
     * 0 => dateiname
     * 1 => xmin
     * 2 => xmax
     * 3 => length
     * 4 => dimension
     * 5 => maxIt
     */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		double xmin=0.0, xmax=0.0, length=0.0;
		int dimension=0,maxIt=0;
		String dateiname="";
 
			try {
				// Imaginärteil
				xmin = Double.parseDouble(args[1]); //-2
				xmax = Double.parseDouble(args[2]); //-2
				length = Double.parseDouble(args[3]); //4
 
				// Realteil
				dimension = Integer.parseInt(args[4]); //400
				maxIt = Integer.parseInt(args[5]); //254
				dateiname = args[0]; //mandelbrot.pgm
 
			} catch(Exception e) {
				error_msg("Fehler bei der Eingabe");
			}
 
			//Andere Fehler abfangen
			if(dimension <= 0) error_msg("Fehler: Dimension <= 0");
			if(length <= 0) error_msg("Fehler: Laenge <= 0");
			if(maxIt <= 0) error_msg("Fehler: Grauwert <= 0");
 
 
			int draw[][] = new int[dimension][dimension];
			//double d_dimension = (double)dimension; //perfomanter als in der schleife zu casten?
 
			// x & y => Imaginärteil in Mandelfeldern (z.B. -2 bis 2)
			// i & j => Realteil in Pixeln (z.B. 0 bis 400)
			double x=xmin;
			for (int i=0 ; i<dimension ; i++) {
				double y=xmax;
				for (int j=0 ; j<dimension ; j++) {
					draw[j][i] = greytone(x, y, maxIt);
					y += length / dimension;
				}
				x += length / dimension; //Schrittweite = Quotient von Länge(Imaginär) und Bildgröße(Real)
			}
 
			try {
				pgm(draw, dateiname, dimension, maxIt);
			} catch(Exception e) {
				System.out.println("Fehler");
			}
 
			System.out.print("Das Mandelbrot wurde erstellt");	
	}
 
	/**
	 * Draws a PGM Picture 
	 * @param draw -> Array
	 * @param filename -> Dateiname
	 * @param maxIt -> Maximaler Grauwert (für den Header)
	 * @throws IOException
	 */
	static void pgm(int[][] draw, String filename, int dimension, int maxIt)  throws IOException
	{
		Formatter output = new Formatter(new File(filename));
 
		// Header schreiben
		output.format("P2\n#"+filename+"\n"+draw[0].length+" "+draw.length+"\n"+maxIt+"\n");
 
		// Array schreiben
		for(int i=dimension-1; i>=0; i--) { //umgekehrt steht "es" auf den Fuessen
			for(int point : draw[i])
				output.format(point+" ");
			output.format("\n");
		}
		output.close();
	}
 
	/**
	 * Returns the Greytone
	 * @param xmin = imaginärteil - x-Koordinate
	 * @param xmax = imaginärteil - y-Koordinate
	 * @param maxIt
	 * @return
	 */
	static int greytone(double xmin, double xmax, int maxIt) {
		double old_x, old_y, new_x=0, new_y=0;
 
		int greytone = maxIt; //von 0 oder von 1?
 
		do {
			old_x = new_x;
			old_y = new_y;
 
			// x_1 = x_0^2 - y_0^2 + x_1 ~> (1)
			new_x = (old_x * old_x) - (old_y * old_y) + xmin;
			// y_1 = 2 * x_0 * y_0 + y_1 ~> (1)
			new_y = 2 * (old_x * old_y) + xmax;
 
			greytone--;
 
			// Betrag = sqrt(a_1^2 + b_1^2)
			// Bedingung = Betrag^2 < 4 
			if ((new_x*new_x) + (new_y*new_y) >= 4) 
				return greytone;
 
		} while (greytone > 0);
 
		return greytone;
	}	
	//Quellen: (1) http://www.mathematische-basteleien.de/apfelmaennchen.htm
 
	static void error_msg(String text)
	{
		System.out.println(text);
		System.exit(-1);
	}
}
Torben Brodt has attached the following image:
  • mandelbrot.gif

2

Friday, January 6th 2006, 10:34am

Meine Lösung:

Hallo miteinander,
hier meine Lösung des Problems, die Grauwerte werden rekursiv errechnet, Imaginär- und Realteil in einem 3-Dimensionalen Array gespeichert. Ab einer Pixelzahl von 1000 kann es daher zu einem "java.lang.OutOfMemoryError: Java heap space" Error kommen.


Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import java.util.*;
import java.io.*;
 
/**
 * Medieninformatik, I.Semester / FH-Wiesbaden<br>
 * Ubungsblatt 10<br>
 * <br>
 * Das Programm erzeugt eine Datei, welche einen beliebigen Ausschitt der Mandelbrot-Menge zeigt<br>
 * <br>
 * getestet mit WinXP, Servicepack2 / Java 5.0<br>
 * @author Sebastian Schmitt
 * @version 1.0
 */
 
 
 
public class mandelbrot {
 
	/**
	 * @param args Komadozeilenparameter
	 */
	public static void main(String[] args) 
	throws FileNotFoundException{
 
		if (args.length!=6 || !(isStringDouble(args[0])) || !(isStringDouble(args[1])) ||//pruefe Abbruchbedingungen
			!(isStringDouble(args[2])) || !(isStringInt(args[3])) || !(isStringInt(args[4])))
			error();
		else{
			double leftx = Double.parseDouble(args[0]);	//linker rand 
			double lefty = Double.parseDouble(args[1]);	//unterer rand
			double size  = Double.parseDouble(args[2]);	//groesse
			int pixel = Integer.parseInt(args[3]);			//Anzahl pixel pro Achse
			int grey  = Integer.parseInt(args[4]);			//AnzahlGraustufen
 
 
			double field[][][] = new double [pixel][pixel][2];	//Erzeuge Array
 
			double delta = size/pixel;
 
			for (int i=0;i<pixel;i++)				//Weise den Arrayfeldern die Werte der komplexen Zahlen zu
				for (int j=0; j<pixel;j++){
					field [i][j][0]= leftx + (i*delta);
					field [i][j][1]= lefty + size - (j*delta);
				}
 
			int grauwerte[][]= new int [pixel][pixel];//Erzeuge neues Array für ergebnisse
 
			for (int i=0;i<pixel;i++)			//schreibt in das neue Array ueber die rekursive
				for (int j=0;j<pixel;j++){	//Funktion konvergenz() die Ergebnisse/Grauwerte
					grauwerte[i][j]=grey - konvergenz(field[i][j][0],field[i][j][1],0,0,0,grey);
				}
 
			Formatter ausgabe = new Formatter (new File(args[5])+".pgm");
 
			ausgabe.format("%s\n %s %s\n %s %s\n %s\n","P2","#",args[5]+".pgm",pixel,pixel,grey);
												//Formatiert den Kopf der pgm-Datei
			for (int i=0;i<pixel;i++)			//Schreibt die Grauwerte in die pgm-Datei
				for (int j=0;j<pixel;j++){
					if (j==pixel-1)
						ausgabe.format("%2d\n ",grauwerte[j][i]);
					else
						ausgabe.format("%2d ",grauwerte[j][i]);
				}
			ausgabe.close();
		}
	}
 
	/**
	 * Die Funktion errechnet rekursiv die Werte der Mandelbrot-Folge
	 * 
	 * @param a Realteil d. Kompl. Zahl
	 * @param b Imaginaerteil d. Kompl. Zahl
	 * @param c Re(n-1)
	 * @param d Im(n-1)
	 * @param z Zaehler
	 * @param max maximale Graustufen
	 * @return Anzahl maximaler Iterationen
	 */
	static int konvergenz(double a,double b,double c,double d, int z, int max){
		if (((c*c)+(d*d))>4)
			return z;
		else if (z==0)
			return konvergenz(a,b,a,b,z+1,max);
		else if (z==max)
			return z;
		else
			return konvergenz(a,b,(c*c)-(d*d)+a,(2*c*d)+b,z+1,max);
	}
	/**
	 * Die Funktion prueft, ob ein String ein Double ist 
	 * @param str Komandozeilenparameter-String
	 * @return true/false
	 */
	static boolean isStringDouble(String str){
 
		char zahl[]=new char [str.length()];
		int zaehler=0,punkt=0;
 
		for (int i=0;i<str.length();i++){
			zahl[i]=str.charAt(i);
			if ( !((Character.isDigit(zahl[i])) || (zahl[i]=='.') || (zahl[i]=='-')))
				zaehler+=1;
			if (zahl[i]=='.')
				punkt+=1;
		}						
		if (zaehler!=0 || punkt>1) return false;
		else			   return true;
 
	}
	/**
	 * Die Funktion prueft, ob ein String ein Integer ist 
	 * @param str Komandozeilenparameter-String
	 * @return true/false
	 */
	static boolean isStringInt(String str){
 
		char zahl[]=new char [str.length()];
		int zaehler=0;
 
		for (int i=0;i<str.length();i++){
			zahl[i]=str.charAt(i);
			if ( !((Character.isDigit(zahl[i])) || (zahl[i]=='-')))
				zaehler+=1;
		}						
		if (zaehler==0) return true;
		else			   return false;
 
	}
	/**
	 * Die Funktion informiert bei falscher Benutzung 
	 * ueber die Handhabung des Programmes
	 */
	static void error(){
		System.out.println("Falsche Eingaben, bitte beim naechsten Mal folgendermassen vorgehen:");
		System.out.println("- param1 u. param2: geben die untere, linke Ecke des Bildausschnittes an ");
		System.out.println("- param3: gibt die groesse des Bildausschnittes an ");
		System.out.println("- param4: gibt die Anzahl der Pixel horizontal und vertikal an");
		System.out.println("- param5: gibt die Anzahl der Graustufen an ");
		System.out.println("- param6: gibt den Namen der Zieldatei an (Bitte ohne Endung!)");
	}
 
}

Similar threads

Social bookmarks