Created
January 22, 2013 07:03
-
-
Save non/4592704 to your computer and use it in GitHub Desktop.
Simple example I'm cooking up...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package spire.example | |
| import spire.implicits._ | |
| import spire.math._ | |
| import spire.syntax._ | |
| import scala.annotation.tailrec | |
| object MandelbrotDemo { | |
| /** | |
| * Compute whether the complex number c stays contained within a radius-2 | |
| * circle after 'limit' iterations. | |
| */ | |
| def mandelbrot(c: Complex[Double], limit: Int): Int = { | |
| @tailrec def loop(z: Complex[Double], n: Int): Int = | |
| if (n >= limit) n | |
| else if (z.abs > 2.0) n - 1 | |
| else loop(z * z + c, n + 1) | |
| loop(c, 1) | |
| } | |
| /** | |
| * Print an ASCII approximation of the 4x4 box from -2-2i to 2+2i. | |
| */ | |
| def main(args: Array[String]) { | |
| val res = 26 // number of iterations to try before including pt in the set | |
| val rows = if (args.isEmpty) 20 else args(0).toInt // rows to print | |
| val cols = rows * 2 // cols to print. most fonts are roughly 1:2 | |
| val h = 4.0 / rows // height per pixel character | |
| val w = 4.0 / cols // width per pixel character | |
| def pt(x: Int, y: Int) = Complex(x * w - 2.0, y * h - 2.0) | |
| def display(s: String, n: Int) = print(Xterm.rainbow(n) + s) | |
| // render the area in ASCII, using o's and spaces. | |
| cfor(0)(_ <= rows, _ + 1) { y => | |
| cfor(0)(_ <= cols, _ + 1) { x => | |
| // if n<res, color the pixel accordingly, otherwise then we | |
| // treat it as being in the set. | |
| val n = mandelbrot(pt(x, y), res) | |
| val pixel = if (n == res) " " else "x" | |
| display(pixel, n) | |
| } | |
| println(Xterm.clear()) | |
| } | |
| } | |
| } | |
| object Xterm { | |
| // r, g, b should be 0-5 | |
| def color(r: Int, g: Int, b: Int) = "\033[38;5;%dm" format (16 + b + (g * 6) + (r * 36)) | |
| def clear() = "\033[0m" | |
| // given things like rgb(0xffcc99) produce things like color(6, 5, 4) | |
| def rgb(n: Int) = color(scale(n & 0xff0000), scale(n & 0xff00), scale(n & 0xff)) | |
| private def scale(n: Int) = round((n * 6.0) / 255).toInt | |
| // 0-25 are colors, 26+ is clear | |
| def rainbow(n: Int) = | |
| if (n < 6) Xterm.color(5, n, 0) | |
| else if (n < 11) Xterm.color(10 - n, 5, 0) | |
| else if (n < 16) Xterm.color(0, 5, n - 10) | |
| else if (n < 21) Xterm.color(0, 20 - n, 5) | |
| else if (n < 26) Xterm.color(n - 20, 0, 5) | |
| else Xterm.clear() | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment