2019年9月14日土曜日

開発環境

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES) (Alan A.A. Donovan(著)、Brian W. Kernighan(著)、柴田 芳樹(翻訳)、丸善出版)の第5章(関数)、5.3(複数戻り値)、練習問題5.6の解答を求めてみる。

コード

package main

import (
 "fmt"
 "log"
 "math"
 "net/http"
 "strconv"
)

const (
 width, height = 600, 320
 cells         = 100
 xyrange       = 30.0
 xyscale       = width / 2 / xyrange
 zscale        = height * 0.4
 angle         = math.Pi / 6
)

var sin30, cos30 = math.Sin(angle), math.Cos(angle)

func main() {
 handler := func(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "image/svg+xml")
  fmt.Println(r.URL)
  if err := r.ParseForm(); err != nil {
   log.Print(err)
  } else {
   var (
    formWidth, formHeight int
    formColor             string
   )
   form, bln := r.Form["width"]
   if bln {
    t, err := strconv.Atoi(form[0])
    if err != nil {
     formWidth = width
    } else {
     formWidth = t
    }
   } else {
    formWidth = width
   }
   form, bln = r.Form["height"]
   if bln {
    t, err := strconv.Atoi(form[0])
    if err != nil {
     formHeight = height
    } else {
     formHeight = t
    }
   } else {
    formHeight = height
   }
   form, bln = r.Form["color"]
   if bln {
    formColor = form[0]
   } else {
    formColor = "green"
   }
   fmt.Println(formWidth, formHeight, formColor)
   fmt.Fprintf(w, "<svg xmlns='http://www.w3.org/2000/svg' "+
    "style='stroke: grey; fill: %s; stroke-wdith: 0.7' "+
    "width='%d' height='%d'>\n", formColor, formWidth, formHeight)
   for i := 0; i < cells; i++ {
    for j := 0; j < cells; j++ {
     ax, ay, aOk := corner(i+1, j)
     bx, by, bOk := corner(i, j)
     cx, cy, cOk := corner(i, j+1)
     dx, dy, dOk := corner(i+1, j+1)
     if aOk && bOk && cOk && dOk {
      fmt.Fprintf(w,
       "<polygon points='%g,%g,%g,%g,%g,%g,%g,%g' />\n",
       ax, ay, bx, by, cx, cy, dx, dy)
     }
    }
   }
   fmt.Fprintf(w, "</svg>\n")
  }
 }
 http.HandleFunc("/", handler)
 log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func corner(i, j int) (sx float64, sy float64, finite bool) {
 x := xyrange * (float64(i)/cells - 0.5)
 y := xyrange * (float64(j)/cells - 0.5)
 z, ok := f(x, y)
 if !ok {
  fmt.Printf("z=%g\n", z)
  sx = 0
  sy = 0
  finite = false
  return
 }
 sx = width/2 + (x-y)*cos30*xyscale
 sy = height/2 + (x+y)*sin30*xyscale - z*zscale
 if !isFinite(sx) || !isFinite(sy) {
  fmt.Printf("sx=%g, sy=%g\n", sx, sy)
  finite = false
  sx = 0
  sy = 0
  finite = false
 }
 return
}

func f(x, y float64) (value float64, finite bool) {
 r := math.Hypot(x, y)
 value = math.Sin(r) / r
 finite = isFinite(value)
 if !finite {
  fmt.Printf("value=%g\n", value)
 }
 return
}

func isFinite(f float64) (finite bool) {
 finite = math.Abs(f) < math.Inf(1)
 return
}

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

$ go run sample6.go
/
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/?color=red&width=500&height=250
500 250 red
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/favicon.ico
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/?width=320&height=600
320 600 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
/favicon.ico
600 320 green
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
signal: terminated
$ 

0 コメント:

コメントを投稿