JAVA Mandelbrot-Menge

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • 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)

    Source Code

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

      33.6 kB, 615×432, viewed 2,696 times
  • 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.


    Source Code

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