Skip to content

Instantly share code, notes, and snippets.

@whyrusleeping
Created May 10, 2013 22:45
Show Gist options
  • Save whyrusleeping/5557986 to your computer and use it in GitHub Desktop.
Save whyrusleeping/5557986 to your computer and use it in GitHub Desktop.
some go mandlebrot code
package main
import (
"fmt"
"runtime"
"image"
"image/color"
"image/png"
"math"
"os"
)
type MandlebrotInfo struct {
botLeft, topRight complex128
x,y int
points [][]byte
complete int
}
func NewMandlebrot(x, y, segments int) *MandlebrotInfo {
m := new(MandlebrotInfo)
m.x = x
m.y = y
m.botLeft = complex(-2.0, -1)
m.topRight = complex(1,1)
m.points = make([][]byte, segments)
return m
}
func (mi *MandlebrotInfo) Render(Color func(b byte) color.Color, outfile string) error {
x, y := 0,0
rect := image.Rect(0,0,mi.x,mi.y)
img := image.NewRGBA(rect)
for i := 0; i < len(mi.points); i++ {
for j := 0; j < len(mi.points[i]); j++ {
if x == mi.x {
x = 0
y++
}
img.Set(x,y, Color(mi.points[i][j]))
x++
}
}
fi, err := os.Create(outfile)
if err != nil {
return err
}
err = png.Encode(fi, img)
return err
}
func BlueishGradient(b byte) color.Color {
col := color.RGBA{}
col.R = uint8(255 * math.Sin(math.Pi * float64(b)))
col.G = uint8(255 * (math.Pow(math.Sin(math.Pi * float64(b)), 2) + float64(1 - b)) / 2)
col.B = uint8(255 * math.Sin(float64(1 - b)))
col.A = 255
return col
}
func BlackAndWhite(b byte) color.Color {
col := color.Gray{}
if b == 0 {
col.Y = 0
} else {
col.Y = 255
}
return col
}
func (mi *MandlebrotInfo) GetNextTask() *MandleSegment {
if mi.complete == len(mi.points) {
return nil
}
ms := new(MandleSegment)
ms.sizeX = mi.x
ms.sizeY = mi.y
ms.botLeft = mi.botLeft
ms.topRight = mi.topRight
N := 0
for i := mi.complete; i < len(mi.points); i++ {
if mi.points[i] == nil {
N = i
break
}
}
mi.complete++
count := len(mi.points)
ms.startY = N * (mi.y / count)
ms.endY = (N + 1) * (mi.y / count)
fmt.Printf("%d %d\n", ms.startY, ms.endY)
return ms
}
type MandleSegment struct {
botLeft, topRight complex128
sizeX, sizeY int
startY, endY int
}
func calcMandlebrot(c complex128) int {
var z complex128
iterations := 0
for ;iterations < 256 && real(z) <= 4; iterations++ {
z = c + (z * z)
}
return iterations
}
func (mi *MandleSegment) calcMandleSegment() []byte {
ret := make([]byte, (mi.endY - mi.startY) * mi.sizeX)
i := 0
for y := mi.startY; y < mi.endY; y++ {
for x := 0; x < mi.sizeX; x++ {
a := real(mi.botLeft) + (float64(x) * (real(mi.topRight) - real(mi.botLeft)) / float64(mi.sizeX - 1))
b := imag(mi.topRight) - (float64(y) * (imag(mi.topRight) - imag(mi.botLeft)) / float64(mi.sizeY - 1))
c := complex(a, b)
ret[i] = byte(calcMandlebrot(c))
i++
}
}
return ret
}
func main() {
runtime.GOMAXPROCS(4)
m := NewMandlebrot(27000,18000, 4)
a := m.GetNextTask()
b := m.GetNextTask()
c := m.GetNextTask()
d := m.GetNextTask()
af := a.calcMandleSegment()
bf := b.calcMandleSegment()
cf := c.calcMandleSegment()
df := d.calcMandleSegment()
m.points[0] = af
m.points[1] = bf
m.points[2] = cf
m.points[3] = df
fmt.Println("Calculations complete, now rendering...")
err := m.Render(BlueishGradient, "testout.png")
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment