Skip to content

Instantly share code, notes, and snippets.

@linus
Created December 27, 2010 19:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linus/756446 to your computer and use it in GitHub Desktop.
Save linus/756446 to your computer and use it in GitHub Desktop.
Mandelbrot set in CoffeeScript and Canvas
# Complex class from http://docstore.mik.ua/orelly/webprog/jscript/ch08_05.htm#jscript4-CHP-8-EX-6
class Complex
constructor: (@x, @y) ->
magnitude: ->
Math.sqrt @x * @x + @y * @y
negative: ->
new Complex -@x, -@y
toString: ->
"{" + @x + "," + @y + "}"
valueOf: ->
@x
add: (complex) ->
new Complex @x + complex.x, @y + complex.y
subtract: (complex) ->
new Complex @x - complex.x, @y - complex.y
multiply: (complex) ->
new Complex @x * complex.x - @y * complex.y, @x * complex.y + @y * complex.x
# Export class to window
@Complex = Complex
# Function to plot the Mandelbrot set to a canvas, using maxIterations iterations
@mandelbrot = (canvas, maxIterations) ->
# Range of x points
xprange = [0...canvas.width]
# Range of y points
yprange = [0...canvas.height]
# Range of x coordinates on the complex plane, from -2.25 to 0.75, mapped to the width of the canvas
xcoords = (xp / canvas.width * 3 - 2.25 for xp in xprange)
# Range of y coordinates on the complex plane, from -1 to 1, mapped to the height of the canvas
ycoords = (yp / canvas.height * 2 - 1 for yp in yprange)
# Store the list of iterations
iterations = [0...maxIterations]
# Iterate over all x points
for x in xprange
# Iterate over all y points
for y in yprange
# Begin with complex point (0, 0)
z = new Complex 0, 0
# With the coordinate in the complex plane corresponding to this point
c = new Complex xcoords[x], ycoords[y]
# Start with black
color = [0, 0, 0]
# Iterate
for i in iterations
# Calculate the new point z = z * z + c
z = z.multiply(z).add(c)
# Check if the new z is bigger than our escape value
if z.magnitude() >= 2.236
# If so, calculate the appropriate color using some cool formula
color = [(i * 2 + 255) % 255, (i * 3 + 255) % 255, (i + 255) % 255]
# Then break out of the loop
break
# Plot the point on our canvas
plot canvas, x, y, color
return
# Converts color array [r, g, b] to CSS color string "rgb(r, g, b)"
rgb = (color) ->
'rgb(' + color.join(',') + ')'
# Plot a point x, y with supplied color on the canvas
plot = (canvas, x, y, color) ->
# Get context
ctx = canvas.getContext('2d')
# Set color
ctx.fillStyle = rgb color
# Plot rectangle from x, y with width, height = 1, 1
ctx.fillRect x, y, 1, 1
<!doctype html>
<html>
<head>
<title>Mandelbrot</title>
<script src="complex.js"></script>
<script src="mandelbrot.js"></script>
</head>
<body onload="mandelbrot(document.getElementById('mandelbrot'), 1000)">
<canvas id="mandelbrot" width="300" height="200"></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment