2019年2月1日金曜日

開発環境

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

コード

package main

import (
 "fmt"
 "math"
 "os"
)

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() {
 file, err := os.Create("sample3.svg")
 if err != nil {
  fmt.Fprint(os.Stderr, err)
  os.Exit(1)
 }
 defer file.Close()
 fmt.Fprintf(file, "<svg xmlns='http://www.w3.org/2000/svg' "+
  "style='stroke: grey; fill: white; stroke-wdith: 0.7' "+
  "width='%d' height='%d'>\n", width, height)
 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)
   z, zOk := polygonZ(i, j)
   if aOk && bOk && cOk && dOk && zOk {
    rgb := int(math.Abs(z*(0xff0000-0x0000ff) + 0x0000ff))
    fmt.Fprintf(file,
     "<polygon points='%g,%g,%g,%g,%g,%g,%g,%g' "+
      "style='fill:#%06x'/>\n",
     ax, ay, bx, by, cx, cy, dx, dy, rgb)
   }
  }
 }
 fmt.Fprintf(file, "</svg>\n")
}

func corner(i, j int) (float64, float64, 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)
  return 0, 0, false
 }
 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)
  return 0, 0, false
 }
 return sx, sy, true
}

func polygonZ(i, j int) (float64, bool) {
 x := xyrange * (float64(i)/cells - 0.5)
 y := xyrange * (float64(j)/cells - 0.5)
 z, ok := f(x, y)
 if !ok {
  return 0, false
 }
 return z, true
}

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

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

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

$ go run sample3.go
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
z=NaN
value=NaN
$ convert sample3.svg sample3.png
$

0 コメント:

コメントを投稿