This repository has been archived on 2021-10-15. You can view files and clone it, but cannot push or open issues or pull requests.
2020-coding-projects/mandelbrot/server/main.go
2020-04-26 15:40:03 +02:00

103 lines
2.4 KiB
Go

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))
}