Mischmasch


Ja, es ist schon eine Weile her, dass ich etwas geschrieben habe. Ich bin etwas im Stress, dabei habe ich mit den Weihnachtseinkäufen noch gar nicht angefangen. Unter anderem bin ich (mehr oder weniger fleißig) am Lernen, denn Anfang Dezember will ich mich wieder an einer Japanisch-Prüfung versuchen (JLPT N3). Das wird wohl verdammt knapp werden…

Inzwischen ist Scala 2.8.1 erschienen, von dem ich bisher nur Gutes gehört habe. Auch der Plan für Java 7 nimmt langsam Gestalt an, auch wenn dieser sehr bescheiden anmutet. Mal sehen ob Oracle es schafft, sich wieder ein wenig Vertrauen zurückzuerobern.

Und zum Schluss noch im Gedenken an Benoît Mandelbrot, der im Oktober verstorben ist, ein kleines Apfelmännchen-Programm.

 
import java.awt.Graphics
import java.awt.event.MouseEvent
import java.awt.event.MouseWheelEvent
import java.awt.event.MouseWheelListener
import java.awt.image.BufferedImage
import javax.swing.JComponent
import javax.swing.JFrame
import javax.swing.event.MouseInputAdapter

object Mandelbrot {

  class ApplePanel extends JComponent {

    var center = (0.0,0.0)
    var scale = 100.0 //1 unit is scale px
    var clickPoint: (Int, Int) = _

    val mia = new MouseInputAdapter {
      override def mousePressed(e: MouseEvent) {
        clickPoint = (e.getX, e.getY)
      }
   
      override def mouseDragged(e: MouseEvent) = updateSize(e)

      override def mouseReleased(e: MouseEvent) = updateSize(e)

      def updateSize(e: MouseEvent) {
        center = (center._1 + (clickPoint._1 - e.getX)/scale,
                  center._2 + (clickPoint._2 - e.getY)/scale)
        clickPoint = (e.getX, e.getY)
        repaint()
      }
    }

    addMouseMotionListener(mia)
    addMouseListener(mia)
    addMouseWheelListener(new MouseWheelListener{
        override def mouseWheelMoved(e: MouseWheelEvent) {
          if (e.getWheelRotation > 0) scale *= 0.9 else scale *= 1.1
          repaint()
        }
    })

    override def paintComponent(g: Graphics) {
      val bi = new BufferedImage(getWidth+1, getHeight+1, BufferedImage.TYPE_INT_RGB)
      val x0 = center._1 - getWidth/(2*scale)
      val y0 = center._2 - getHeight/(2*scale)
      for(x <- 0 to getWidth; y <- 0 to getHeight) {
        var k = 0
        val cx = x0 + x/scale
        val cy = y0 + y/scale
        var zx = 0.0
        var zy = 0.0

        //shortcut for central areas
        val q = (cx - 0.25)*(cx - 0.25) + cy * cy
        if (q*(q + (cx - 0.25)) < 0.25 * cy*cy) k = 10000
        if ((cx+1)*(cx+1) + cy*cy < 1.0/16) k = 10000

        while(k < 1000 && zx*zx + zy*zy < 4) {
          val temp = zx*zx -zy*zy + cx
          zy = 2*zx*zy + cy
          zx = temp
          k += 1
        }
        if (zx*zx + zy*zy < 4) {
          bi.setRGB(x, y, 255)
        } else {
          bi.setRGB(x, y, 256*256 * math.min(255, 10 * k) + 256 * math.min(255, k))
        }
      }
      bi.setRGB(10, 10, 255)
      g.drawImage(bi, 0, 0, null)
    }
  }

  def main(args: Array[String]) {
    new JFrame{
      setTitle("Mandelbrot")
      setSize(500, 500)
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
      getContentPane.add(new ApplePanel)
      setVisible(true)
    }
  }
}

Man kann das Bild mit der Maus ziehen und mit dem Mausrad zoomen. Ich habe versucht, eine gute Balance zwischen guter Auflösung und Reaktionszeit zu finden, aber schwächere Rechner werden trotzdem zu knabbern haben. Da das Programm sehr eventlastig ist, habe ich auf Scala-Swing verzichtet.

Natürlich gibt es bereits jede Menge gute Fraktalprogramme, das hier ist im Vergleich nur eine kleine Spielerei. Ich hoffe, es macht euch trotzdem Spaß.

Hinterlasse einen Kommentar

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..