Generating the Batman Equation using a Monte Carlo Simulation

The BatMan equation has been making the rounds on the internet recently. The Go code below uses the Plotium library to plot the results.

package main
 
import (
	"code.google.com/p/plotinum/plot"
	"code.google.com/p/plotinum/plotter"
	"math"
	"math/rand"
	"time"
)
 
func main() {
	rand.Seed(time.Now().Unix())
	p, err := plot.New()
	s, err := plotter.NewScatter(batman(90000))
	s.Shape = plot.CircleGlyph{}
	p.Add(s)
	err = p.Save(8, 4, "points.png")
	if err != nil {
		panic(err)
	}
}
 
func batman(n int) plotter.XYs {
	pts := make(plotter.XYs, n)
	for i := 0; i < n; i++ {
		pts[i].X = rand.Float64()*14.0 - 7.0
		if i < n/2 {
			pts[i].Y = up(pts[i].X)
		} else {
			pts[i].Y = down(pts[i].X)
		}
	}
	return pts
}
 
func down(x float64) float64 {
	if math.Abs(x) > 4 {
		return -wings(x)
	} else {
		return tail(x)
	}
}
 
func up(x float64) float64 {
	switch {
	case math.Abs(x) > 3:
		return wings(x)
	case math.Abs(x) > 1:
		return arms(x)
	case math.Abs(x) > 0.75 && math.Abs(x) < 1:
		return neck(x)
	case math.Abs(x) > 0.5 && math.Abs(x) < 0.75:
		return ears(x)
	default:
		return head(x)
	}
}
 
func head(x float64) float64 {
	return 2.25
}
 
func ears(x float64) float64 {
	return 3.0*math.Abs(x) + 0.75
}
 
func neck(x float64) float64 {
	return 9.0 - 8.0*math.Abs(x)
}
 
func arms(x float64) float64 {
	m := 4.0 - math.Pow(math.Abs(x)-1.0, 2)
	return 2.71 - 0.5*math.Abs(x) + 1.5 - 1.35*math.Sqrt(m)
}
 
func tail(x float64) float64 {
	y1 := math.Abs(x / 2.0)
	y2 := x*x*0.09 + 3.0
	y3 := math.Abs(math.Abs(x)-2.0) - 1.0
	y4 := math.Sqrt(1.0 - y3*y3)
	return y1 - y2 + y4
}
 
func wings(x float64) float64 {
	return 3.0 * math.Sin(math.Acos(x/7.0))
}

The result:

Batman Equation