2019年2月23日土曜日

開発環境

プログラミング言語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
}

入出力結果(cmd(コマンドプロンプト)、Terminal)

C:\Users\...> go run sample9.go 
/
赤 3774、 緑 3829、青 3766、黄 3831、黒 1184
/
赤 3774、 緑 3829、青 3766、黄 3831、黒 1184
/?scale=2
赤 15220、 緑 15339、青 15211、黄 15344、黒 4422
/?scale=2&x=2&y=3
赤 12485、 緑 12530、青 18428、黄 18585、黒 3508

C:\Users\...>

0 コメント:

コメントを投稿