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: