2D-Grafik Problem mit MandelbrotMenge

Strece

Mitglied
Hallo,

also ich und ein Kollege sitzen grade an einem Programm, dass die MandelbrotMenge ausgeben soll.
Wir sind zwar schon soweit gekommen, das hoffentlich die Berechnungen stimmen, aber der Helligkeitswert den wir einer setColor übergeben ist immer 1, also schwarz.

Irgendwie stimmen wohl unsere Berechnungen nicht oder wir verstehen die Aufgabenstellung falsch.

Hier mal der Java Code:
Java:
import java.awt.Color;
import java.awt.Point;
import java.awt.*;


public class MandelbrotGraphics {
	private static Point p;
	private static int n;
	private int width;
	private int height;
	private int maxGray;
	private double left;
	private double right;
	private double lower;
	private double upper;
	


    public static void mandelbrot
        (GraphicsWindow gw,
         int width, int height, int maxGray,
         double left, double right, double lower, double upper) 
    {
    	//Point p = new Point(x, y);
    	double point_y = 0.0;
    	double temp1 = 0;
    	double temp2 = 0;
    	
       
   	    for (int y = 0; y < height; y++) 
   	    {
   	    	double point_x = 0.0;
   	    	for (int x = 0; x < width; x++)
   	    	{
   	    		
   	    		
   	    		int n = 0;
   	   	        int n_max = maxGray;
   	   	        
   	   	        
   	 	        double n2 = 0;
   	 	  
   	 	        //gw.setText("x" + point_x);
   	 	        //gw.mouseClick();
   	 	        
   	 	        
   	    		while(n < n_max && n2 < 3.0)
   	    		{
   	    			double tempx = point_x;
   	    			double tempy = point_y;
   	    			point_x = point_x * point_x - point_y * point_y + x;
		    		point_y = 2 * tempx * tempy + y;
		    		n2 = Math.sqrt(point_x * point_x + point_y * point_y);
		    		n++;
   	    		}
		    		 
   	    		
	    		gw.setMandelColor(n);
	   	    	gw.drawPoint(new Point(x,y));
	   	    	
	   	    	temp1 = temp1 + (right - left)/width;
	   	    	point_x = temp1;
	   	    	gw.setText("n" + n);
   	    		gw.mouseClick();
   	   	        //point_x = left + temp2;
   	    	
   	    	}
   	    	temp2 = temp2 + (lower - upper)/height;
   	    	point_y = temp2;
   	    	//point_y = upper + temp;
   	    }
    }
    
    
      
  public static void main (String[] argv) {
    	
        int width    = Integer.parseInt("320");
        int height   = Integer.parseInt("240"); 
        int maxGray  = Integer.parseInt("25");
        double left  = Double.parseDouble("-2.9");
        double right = Double.parseDouble("1.1");
        double lower = Double.parseDouble("-1.5");
        double upper = Double.parseDouble("1.5");
	  
       
        mandelbrot(new GraphicsWindow(width,height), 
                   width, height, maxGray,
                   left, right, lower, upper);
        
    }
}

Und die Aufgabenstellung:
Mit sehr einfachen mathematischen Formeln kann man
manchmal sehr beeindruckende Graphiken produzieren; diese
sind unter dem Namen Fraktale bekannt. In dieser Aufgabe
werden Sie angeleitet, die Graphik Mandelbrot-Menge,
auch bekannt als \Apfelmannchen", zu erstellen.
Bekanntermaßen ist j(x; y)j =
p
x2 + y2 der Abstand eines Punktes (x; y) 2 R2 zum
Ursprung (0; 0). Der Helligkeitswert n eines Punktes (x; y) mit reellen Zahlen x; y wird durch
folgende Iteration berechnet:
x0 = 0 y0 = 0
xn+1 = x2n² - y2n² + x
yn+1 = 2*xn*yn + y
Ist zu einem Zeitpunkt n der Abstand von (xn; yn) zum Ursprung größer 3, so ist der Helligkeitswert
des Punktes (x; y) gleich n. Ein Punkt ist um so heller, je langer wir die Iteration
durchfuhren mussen, um einen Abstand größer 3 zum Ursprung zu bekommen. Es gibt auch
Punkte, die sich nie wesentlich vom Ursprung entfernen z.B. (x; y) = (0; 0). Fur solche Punkte
konnen wir den Helligkeitswert nicht berechnen, er ware unendlich. Deswegen setzen wir ein
maximalen Wert N fur n fest und iterieren nur solange, wie n < N. Ist nach N Schritten die
Iteration nicht beendet, bekommt Punkt (x; y) den Helligkeitswert 0 (schwarz).
Auf einem Rechner kann man naturlich immer nur einen endlichen Ausschnitt der Ebene
R2 darstellen, und den auch nur mit endlich vielen Pixeln. Zum Beispiel wollen wir den
Auschnitt einschließlich (??2:9; 1:5) (linkere obere Ecke) bis ausschließlich (1:1;??1:5) (rechte
untere Ecke) auf einem Bild der Größe 4 x 3 Pixel darstellen. Wir mussen dann die Helligkeitswerte
folgender Punkte (x; y) berechnen:

Ich hoffe jemand kann uns vielleicht ein wenig Hilfestellung geben um dann doch zur Lösung zu gelangen.

Mfg,

Strece
 
Moin,

ohne mich jetzt durch den gesamten Code (geschweige denn die Aufgabenstellung!) gewühlt zu haben :

Meinst Du diese Stelle :
Java:
gw.setMandelColor( n );

da diese Zeile hinter der while-Schleife liegt, vermute ich mal, dass das 'n' bis 'n_max' gelaufen ist und somit auf "maxGray" steht - was immer da übergeben worden ist ... vlt. "Schwarz" ??v
EDIT: Ach so - immer fix 25 !

Gruß
Klaus

BTW:
warum statt
Java:
int width    = Integer.parseInt("320");
int height   = Integer.parseInt("240"); 
int maxGray  = Integer.parseInt("25");

nicht gleich :
Java:
int width    = 320;
int height   = 240;
int maxGray = 25;
???:L

Was genau ist hier 25 ???:L
 
Zuletzt bearbeitet:
Hey

Danke für deine Antwort.
Stimmt natürlich das Integer.parseInt gehört da nicht hin.
maxGrey ist der maximale Helligkeits wert, wobei 0 schwarz bedeutet und die anderen Werte eine andere Farbe ergeben. Die Methode setMandelColor(n) gibt somit schwarz oder eine andere Farbe zurück.

Wenn ich die Aufgabe richtig verstanden habe dann soll n nur schwarz ergeben wenn die Iteration ohne den Betrag von 3 zu überschreiten beendet wird. Ansonsten den aktuellen n-Wert.
25 ist somit nur eine Begrenzung.

Ich hoffe es ist nun klarer.
 
Hm... Wenn maxGray ein "üblicher" Helligkeitswert ist, geht der von 0 bis 255, und dann könnte es sein dass man 25 (je nach Monitor) nur als Schwarz wahrnimmt (ganz, ganz dunkel grau). Eine Debug-Ausgabe mit
System.out.println("Bei "+x+" "+y+" war es "+n);
könnte schon helfen, oder maxGray auf 255 hochsetzen. Leider kann man es ohne die fehlenden Klassen ja nicht testen.
(Ganz nebnebei: Ihr werdet Geduld brauchen 😉 So ein Math.sqrt ist der Killer, aber könnte dort sehr leicht vermieden werden...)
 
Ohne jetzt irgendeine Ahnung von der Mathematischen Thematik hier zu haben:
Wikipedia hat gesagt.:
FUNCTION punkt_iteration (cx, cy, max_betrag_quadrat, max_iter)

betrag_quadrat = 0
iter = 0
x = 0
y = 0

WHILE ( betrag_quadrat <= max_betrag_quadrat ) AND ( iter < max_iter )
xt = x * x - y * y + cx
yt = 2 * x * y + cy
x = xt
y = yt
iter = iter + 1
betrag_quadrat = x * x + y * y
END

punkt_iteration = iter

END FUNCTION
Zum Vergleich:
Java:
while(n < n_max && n2 < 3.0)
{
      double tempx = point_x;
      double tempy = point_y;
      point_x = point_x * point_x - point_y * point_y + x;
      point_y = 2 * tempx * tempy + y;
      n2 = Math.sqrt(point_x * point_x + point_y * point_y);
      n++;
}
Ist es gewollt, dass bei jeder Iteration point_x auf 0 gesetzt wird, point_y aber so bleibt und in die Nächste iteration so einfließt? Ich rede über diesen part:
Java:
double point_y = 0.0;
double temp1 = 0;
double temp2 = 0;

for (int y = 0; y < height; y++) 
{
    double point_x = 0.0;
    for (int x = 0; x < width; x++)
 
Zuletzt bearbeitet:
Sofern ich keine Fehler gemacht habe, dann müsste doch, meine Zeile einfach die Kurzform von dem sein:
Code:
xt = x * x - y * y + cx
yt = 2 * x * y + cy
x = xt
y = yt

Aber kann mich auch irren, werde das mal testen und berichten ob es damit besser wird. Danke schonmal
 
Ja, hab's mal getestet, die eigentliche Iteration stimmt fast, aber die Rolle und Bedeutung von point_x/y und x/y sind ziemlich vermischt: In der Iteration addierst du am Ende x bzw. y. Dieses x/y sind aber Pixelkoordinaten - die haben nichts mit der eigentlichen Iteration zu tun. D.h. dort müßte eigentlich der Startwert von point_x und point_y stehen, aber diese Startwerte sind auch noch nicht ganz richtig berechnet: upper und lower werden ja gar nicht verwendet. Schau mal ob du den Punkt (innerhalb des durch upper/lower/left/right beschriebenen Rechtecks) richtig ausrechnen kannst - am einfachsten am Anfang der inneren Schleife. Diesen Punkt dann speichern, und seine x/y-Koordinaten anstelle des x/y bei der Iteration verwenden.
 

Zurück
Oben