package main import ( "fmt" "image" "image/color" "image/png" "log" "math" "math/cmplx" "net/http" "runtime" "strconv" "strings" "sync" "deadbeef.codes/steven/mandelbrot/palette" ) const ( Size = 256 Iterations = (1<<16 - 1) / Brighten Brighten = 1024 ) var ( colors []color.RGBA ) func mandelbrot(c complex128) uint16 { var z complex128 for i := 0; i < Iterations; i++ { z = z*z + c if cmplx.IsNaN(z) { return uint16(i) } } return Iterations } type pixel struct { out *image.RGBA x, y int tileX, tileY int64 tileZoom uint8 wg *sync.WaitGroup } var queue = make(chan pixel) func computeThread() { for p := range queue { val := mandelbrot( complex( (float64(p.x)/Size+float64(p.tileX))/float64(uint(1<= steps[j] && i < steps[j+1] { min = steps[j] max = steps[j+1] minColor = float64(cols[j]) maxColor = float64(cols[j+1]) uintColor := cosineInterpolation(maxColor, minColor, (i-min)/(max-min)) interpolated = append(interpolated, uint32(uintColor)) } } } } for _, pixelValue := range interpolated { r := pixelValue >> 24 & 0xff g := pixelValue >> 16 & 0xff b := pixelValue >> 8 & 0xff a := 0xff interpolatedColors = append(interpolatedColors, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}) } } } } return interpolatedColors } func cosineInterpolation(c1, c2, mu float64) float64 { mu2 := (1 - math.Cos(mu*math.Pi)) / 2.0 return c1*(1-mu2) + c2*mu2 } func linearInterpolation(c1, c2, mu uint32) uint32 { return c1*(1-mu) + c2*mu }