1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
package main
import ( "fmt" "image" "image/color" "image/png" "log" "math/cmplx" "net/http" "strconv" )
func main(){ const ( width, height = 1024, 1024 ) params := map[string] float64 { "xmin": -2, "xmax": 2, "ymin": -2, "ymax": 2, "zoom": 1, }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ for name := range params { s := r.FormValue(name) if s == "" { continue } f, err := strconv.ParseFloat(s, 64) if err != nil { http.Error(w, fmt.Sprintf("query param %s: %s", name, err), http.StatusBadRequest) return } params[name] = f } if params["xmax"] <= params["xmin"] || params["ymax"] <= params["ymin"] { http.Error(w, fmt.Sprintf("min coordinate greater than max"), http.StatusBadRequest) return } xmin, xmax, ymin, ymax, zoom := params["xmin"],params["xmax"],params["ymin"],params["ymax"],params["zoom"] lenX, lenY := xmax - xmin, ymax - ymin midX, midY := xmin + lenX / 2, ymin + lenY / 2 xmin, xmax, ymin, ymax = midX - lenX / 2 / zoom, midX + lenX / zoom / 2, midY - lenY / 2 / zoom, midY + lenY / 2 / zoom img := image.NewRGBA(image.Rect(0,0,width, height)) for py := 0; py < height; py++ { y := float64(py) / height * (ymax - ymin) + ymin for px := 0; px < width; px++ { x := float64(px) / width * (xmax - xmin) + xmin z := complex(x, y) img.Set(px, py, mandelbrot(z)) } } png.Encode(w, img) }) log.Fatal(http.ListenAndServe("localhost:8000", nil))
}
func mandelbrot(z complex128) color.Color{ const iterations = 200 const contrast = 15 var v complex128 for n := uint8(0); n < iterations; n++ { v = v * v + z if cmplx.Abs(v) > 2 { return color.Gray{255 - contrast * n} } } return color.Black }
|