scala/ScalaBook/chapter-06/mandel.scala


// Create an image to save
var iter = 0
val overflow = 1.0e100
var rendImage = drawmandel
// Write generated image to a file
try {
  val file = new java.io.File("mandelbrot.jpg");
  javax.imageio.ImageIO.write(rendImage, "jpg", file);
} catch  { 
  case e: java.io.IOException => 
    println("Could not create/write JPEG image.\nAboring.")
}


def drawmandel : java.awt.image.RenderedImage = { 
  val XScreen = 1024
  val YScreen = 1024
  val bufferedImage = new java.awt.image.BufferedImage(XScreen, YScreen, 
                          java.awt.image.BufferedImage.TYPE_BYTE_GRAY)
  // Create a graphics contents on the buffered image
  val G = bufferedImage.createGraphics()
  var iynew = 0

  val pmin = -2.2 
  val pmax = 0.7 
  val qmin = -1.5 
  val qmax = 1.5 
  
  val DeltaP = (pmax-pmin) / (XScreen - 1)
  val DeltaQ = (qmin-qmax) / (YScreen -1)

  for ( np <- 0 to XScreen - 2 ) { 
    var iy = 0
    var x = pmin + DeltaP*np
    var D = MSetDist(x,qmin)
    while (iy < (YScreen - 1)) {  
      iynew = iy + (Math.floor(Math.max(1.0, Math.min(20.0, D)))).toInt
      var y = iynew*DeltaQ + qmax
      var Dnew = MSetDist(x,y)
      if ( D <= 0.0 )
        G.setColor(java.awt.Color.black);
      else {
        var c = (iter % 15 +1) * 17
        G.setColor(new java.awt.Color(c,c,c))
      }
      G.drawLine(np, iy, np, iynew);
      iy=iynew;
      D=Dnew;
    }
  }
  G.dispose
  return bufferedImage
}


def MSetDist(cx : Double, cy : Double):Double = {
  val MaxIterations = 100;
  val huge = 1000.0;
  var i = 0
  var xorbit = new Array[Double](MaxIterations)
  var yorbit = new Array[Double](MaxIterations)
  var dist = 0.0 
  var xder = 0.0;  var yder = 0.0  
  var temp = 0.0
  var x2 = 0.0 
  var y2 = 0.0 
  var x = 0.0 
  var y = 0.0
  xorbit(0) = 0.0
  yorbit(0) = 0.0;
  iter = 1;
  while ((iter < MaxIterations) && ((x2+y2) < huge)) {
    temp = x2 - y2 + cx
    y = 2.0*x*y + cy
    x = temp
    x2 = x*x
    y2 = y*y
    xorbit(iter) = x
    yorbit(iter) = y
    iter += 1
  }
  if ( (x2+y2) > huge ) {
    xder = 0.0
    yder = 0.0
    var i = 0
    var flag = false
    while ( ( i < iter ) && (! flag) ) {
      temp = 2.0*(xorbit(i)*xder-yorbit(i)*yder+1.0)
      yder = 2.0*(yorbit(i)*xder+xorbit(i)*yder)
      xder = temp
      flag = Math.max(Math.abs(xder), Math.abs(yder)) > overflow
      i += 1
    }
    if (! flag) 
      dist = Math.log(x2+y2)*Math.sqrt(x2+y2)/
             Math.sqrt(xder*xder+yder*yder)               
  }
  return dist
}    
//time scala mandel.scala
//
//real    0m4.063s
//user    0m3.161s
//sys    0m0.172s