## 2019年2月23日土曜日

### Go - 基本データ型 - 複素数(単純なフラクタル、ウェブサーバー、フォーム、パラメーター、倍率)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES) (Alan A.A. Donovan(著)、Brian W. Kernighan(著)、柴田 芳樹(翻訳)、丸善出版)の第3章(基本データ型)、3.3(複素数)、練習問題3.9の解答を求めてみる。

コード

```package main

import (
"fmt"
"image"
"image/color"
"image/png"
"log"
"math"
"math/cmplx"
"net/http"
"os"
"strconv"
)

func main() {
handler := func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.URL)
if err := r.ParseForm(); err != nil {
log.Println(err)
} else {
var (
formX, formY, scale int
)
form, bln := r.Form["x"]
if bln {
t, err := strconv.Atoi(form[0])
if err != nil {
formX = 2
} else {
formX = t
}
} else {
formX = 2
}
form, bln = r.Form["y"]
if bln {
t, err := strconv.Atoi(form[0])
if err != nil {
formY = 2
} else {
formY = t
}
} else {
formY = 2
}
form, bln = r.Form["scale"]
if bln {
t, err := strconv.Atoi(form[0])
if err != nil {
scale = 1
} else {
scale = t
}
} else {
scale = 1
}
redCount = 0
greenCount = 0
blueCount = 0
yelloCount = 0
blackCount = 0
var (
xmin, ymin    = -float64(formX * scale), -float64(formY * scale)
xmax, ymax    = float64(formX * scale), float64(formY * scale)
width, height = 128.0 * scale, 128.0 * scale
)
img := image.NewRGBA(image.Rect(0, 0, width, height))
for py := 0; py < height; py++ {
y := float64(py)/float64(height)*(ymax-ymin) + ymin
for px := 0; px < width; px++ {
x := float64(px)/float64(width)*(xmax-xmin) + xmin
z := complex(x, y)
img.Set(px, py, newton(z))
}
}
err = png.Encode(w, img)
if err != nil {
fmt.Fprint(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("赤 %d、 緑 %d、青 %d、黄 %d、黒 %d\n",
redCount, greenCount, blueCount, yelloCount, blackCount)
}
}
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

var (
redCount   = 0
greenCount = 0
blueCount  = 0
yelloCount = 0
blackCount = 0
)

func newton(z complex128) color.Color {
const (
iterations = 200
contrast   = 15
epsilon    = 0.1
)
guess := z
for n := uint8(0); n < iterations; n++ {
v := cmplx.Pow(guess, 4)
if math.Abs(real(v)-1) < epsilon && math.Abs(imag(v)) < epsilon {
var c color.RGBA
if real(guess) > 0 && math.Abs(imag(guess)) < epsilon {
c = color.RGBA{255 - contrast*n, 0, 0, 255}
redCount++
} else if real(guess) < 0 && math.Abs(imag(guess)) < epsilon {
c = color.RGBA{0, 255 - contrast*n, 0, 255}
greenCount++
} else if imag(guess) > 0 {
c = color.RGBA{0, 0, 255 - contrast*n, 255}
blueCount++
} else {
c = color.RGBA{255 - contrast*n, 255 - contrast*n, 0, 255}
yelloCount++
}
return c
}
guess = (guess + 1/cmplx.Pow(guess, 3)) / 2
}
blackCount++
return color.Black
}
```

```C:\Users\...> go run sample9.go
/

/

/?scale=2

/?scale=2&x=2&y=3

C:\Users\...>
```