《go语言圣经》练习答案--1.7. Web服务

练习 1.12: 修改Lissajour服务,从URL读取变量,比如你可以访问 http://localhost:8000/?cycles=20 这个URL,这样访问可以将程序里的cycles默认的5修改为20。字符串转换为数字可以调用strconv.Atoi函数。你可以在godoc里查看strconv.Atoi的详细说明。

package main

import (
	"image"
	"image/color"
	"image/gif"
	"io"
	"math"
	"math/rand"
	"strconv"
)

import (
	"log"
	"net/http"
	"time"
)

var palette = []color.Color{color.White, color.Black}

const (
	whiteIndex = 0
	blackIndex = 1
)

type lconfig struct {
	cycles float64
	res    float64
	freq   float64
	size   int
	frames int
	delay  int
}

func main() {
	rand.Seed(time.Now().UnixNano())
	lconf := lconfig{
		cycles: 5,
		res:    0.001,
		freq:   rand.Float64() * 3.0,
		size:   100,
		frames: 64,
		delay:  8,
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		confs := r.URL.Query()
		for i, c := range confs {
			switch i {
			case "cycles":
				lconf.cycles, _ = strconv.ParseFloat(c[0], 64)
			case "freq":
				lconf.freq, _ = strconv.ParseFloat(c[0], 64)
			case "res":
				lconf.res, _ = strconv.ParseFloat(c[0], 64)
			case "size":
				lconf.size, _ = strconv.Atoi(c[0])
			case "frames":
				lconf.frames, _ = strconv.Atoi(c[0])
			case "delay":
				lconf.delay, _ = strconv.Atoi(c[0])
			}
		}

		lissajous(w, lconf)
	})

	log.Fatal(http.ListenAndServe("localhost:8000", nil))
	return
}

func lissajous(out io.Writer, set lconfig) {
	anim := gif.GIF{LoopCount: set.frames}
	phase := 0.0 // phase difference
	for i := 0; i < set.frames; i++ {
		rect := image.Rect(0, 0, 2*set.size+1, 2*set.size+1)
		img := image.NewPaletted(rect, palette)
		for t := 0.0; t < set.cycles*2*math.Pi; t += set.res {
			x := math.Sin(t)
			y := math.Sin(t*set.freq + phase)
			img.SetColorIndex(set.size+int(x*float64(set.size)+0.5), set.size+int(y*float64(set.size)+0.5), blackIndex)
		}
		phase += 0.1
		anim.Delay = append(anim.Delay, set.delay)
		anim.Image = append(anim.Image, img)
	}
	gif.EncodeAll(out, &anim)
}

 

posted @ 2022-03-09 17:01  随风而逝的白色相簿  阅读(96)  评论(0编辑  收藏  举报