package main import ( "encoding/json" "log" "net/http" "net/url" "strconv" "github.com/lucasb-eyer/go-colorful" ) type Mandelbrot []uint func (m Mandelbrot) SetPixel(width int, x int, y int, color []uint) { start := y*int(width)*4 + x*4 for i := 0; i < 4; i++ { m[start+i] = color[i] } } func GetColor(iteration uint, maxIterations uint) []uint { c := colorful.Hsl(float64(iteration)/256, 1.0, float64(iteration)/(float64(iteration)+8.0)) return []uint{ uint(c.R * 255), uint(c.G * 255), uint(c.B * 255), 255, } //return []uint{0, 0, 0, 255} } func CalculateMandelbrot(maxIterations uint, minX float64, minY float64, maxX float64, maxY float64, width int, height int) Mandelbrot { mandelbrot := make(Mandelbrot, width*height*4) dx := maxX - minX dy := maxY - minY for row := 0; row < height; row++ { for col := 0; col < width; col++ { cRe := (float64(col)*dx)/float64(width) + minX cIm := (float64(row)*dy)/float64(height) + minY var x float64 var y float64 var iteration uint for ; x*x+y*y <= 4 && iteration < maxIterations; iteration++ { newX := x*x - y*y + cRe y = 2*x*y + cIm x = newX } mandelbrot.SetPixel(width, col, row, GetColor(iteration, maxIterations)) } } return mandelbrot } func GetFloatParameter(query url.Values, name string, defaultValue float64) float64 { if str := query.Get(name); len(str) > 0 { value, err := strconv.ParseFloat(str, 64) if err == nil { return value } } return defaultValue } func GetIntParameter(query url.Values, name string, defaultValue int) int { if str := query.Get(name); len(str) > 0 { value, err := strconv.ParseInt(str, 10, 64) if err == nil { return int(value) } } return defaultValue } func MainHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") query := r.URL.Query() var maxIterations uint = 1000 minX := GetFloatParameter(query, "minX", -2.0) minY := GetFloatParameter(query, "minY", -2.0) maxX := GetFloatParameter(query, "maxX", 2.0) maxY := GetFloatParameter(query, "maxY", 2.0) width := GetIntParameter(query, "width", 1000) height := GetIntParameter(query, "height", 1000) log.Println(minX, minY, maxX, maxY, width, height) json.NewEncoder(w).Encode(CalculateMandelbrot(maxIterations, minX, minY, maxX, maxY, width, height)) } func main() { http.HandleFunc("/", MainHandler) log.Fatal(http.ListenAndServe(":8001", nil)) }