Game-Apps für Smartphones und Tablets

Bern University oh Teacher Education  
HomeOnline-Editor startenDruckenAndroid-TurtlegrafikJava-Online

Mandelbrot-Fraktal


Das Mandelbrot-Fraktal wird nach dem Mathematiker Benoid Mandelbrot benannt, der 1975 den Begriff fractal eingeführt hat. Jede Ausschnittsvergrösserung eines Fraktals ist wieder ein Fraktal.


Unsere Implementierung stellt zuerst das ganze Bild dar. Danach kann mit Ziehen des Fingers ein Ausschnitt gewähl werden. Dieser wird erneut gezeichnet.

Beispiel im Online-Editor bearbeiten

App installieren auf Smartphone oder Tablet

QR-Code

Sources downloaden (Mandelbrot.zip)


   

Programmcode:

package app.mandelbrot;

import android.graphics.*;
import ch.aplu.android.*;
import ch.aplu.util.Monitor;

public class Mandelbrot extends GameGrid implements GGTouchListener
{
  private final double RADIUS_SQUARE = * 2;
  private int maxIterations = 50;
  GGPanel p;
  private Point start, end;

  public Mandelbrot()
  {
    super(truewindowZoom(600));
    setScreenOrientation(LANDSCAPE);
  }

  public void main()
  {
    double ratio = (double)getNbHorzPix() / getNbVertPix();
    double yspan = 3.2/ratio;
    draw(-2.2, 1.0, -yspan/2, yspan/2);
    addTouchListener(thisGGTouch.press | GGTouch.drag | GGTouch.release);
  }

  private void draw(double xmin, double xmax, double ymin, double ymax)
  {
    p = getPanel(Math.min(xmin, xmax), Math.max(xmin, xmax),
      Math.min(ymin, ymax), Math.max(ymin, ymax));
    p.setAutoRefreshEnabled(false);
    setTitle(String.format("Mandelbrot -- xmin: %.3f xmax: %.3f ymin: %.3f ymax: %.3f",
      p.getXmin(), p.getXmax(), p.getYmin(), p.getYmax()));

    for (int xPixel = 0; xPixel < getNbHorzPix(); xPixel++)
    {
      for (int yPixel = 0; yPixel < getNbVertPix(); yPixel++)
      {
        double x_p = p.toUserX(xPixel);
        double y_p = p.toUserY(yPixel);
        int iterCount = getIterCount(x_p, y_p);
        int drawColor = getColorForIterCount(iterCount);
        p.setPaintColor(drawColor);
        p.drawPoint(xPixel, yPixel);
      }
      if (xPixel % 100 == 0) // refresh every 50 columns
        refresh();
    }
    refresh();
  }
 
  private int getColorForIterCount(int it)
  {
    return Color.rgb((30 * it) % 256, (4 * it) % 256,
          255 - (30 * it) % 256);    
  }

  private int getIterCount(double x_p, double y_p)
  {
    if (isStable(x_p, y_p))
      return maxIterations;
    double = 0, y = 0;
    int iter = 0;
    while (isInCircle(x, y) && iter < maxIterations)
    {
      double xt = * - * + x_p;
      double yt = * * + y_p;
      x = xt;
      y = yt;
      iter++;
    }
    return iter;
  }

  private boolean isStable(double x, double y)
  {
    double = Math.sqrt(Math.pow(x - / 4f, 2) + * y);
    return < - * (p * p+ / 4f || (x + 1) * (x + 1) + * < / 16f;
  }

  private boolean isInCircle(double x, double y)
  {
    return Math.pow(x, 2) + Math.pow(y, 2) < RADIUS_SQUARE;
  }

  public static void main(String[] args)
  {
    new Mandelbrot();
  }

  public boolean touchEvent(GGTouch mouse)
  {
    Location = toLocation(mouse.getX(), mouse.getY());
    switch (mouse.getEvent())
    {
      case GGTouch.press:
        start = new Point(l.x, l.y);
        end = new Point(l.x, l.y);
        break;
      case GGTouch.drag:
        Point current = new Point(l.x, l.y);
        end = current;
        break;
      case GGTouch.release:
        draw(p.toUserX(start.x), p.toUserX(end.x), p.toUserY(start.y), p.toUserY(end.y));
        break;
    }
    return true;
  }
}