diff --git a/ch1/lissajous/1_5.go b/ch1/lissajous/1_5.go new file mode 100644 index 0000000..e812912 --- /dev/null +++ b/ch1/lissajous/1_5.go @@ -0,0 +1,68 @@ +package main + +import ( + "image" + "image/color" + "image/gif" + "io" + "math" + "math/rand" + "os" +) + +import ( + "log" + "net/http" + "time" +) + +var palette = []color.Color{ + color.Black, + color.RGBA{0x00, 0xff, 0x00, 0xff}, +} + +const ( + whiteIndex = 0 // first color in palette + blackIndex = 1 // next color in palette +) + +func main() { + rand.Seed(time.Now().UTC().UnixNano()) + + if len(os.Args) > 1 && os.Args[1] == "web" { + handler := func(w http.ResponseWriter, r *http.Request) { + lissajous(w) + } + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe("localhost:8000", nil)) + return + } + lissajous(os.Stdout) +} + +func lissajous(out io.Writer) { + const ( + cycles = 5 // number of complete x oscillator revolutions + res = 0.001 // angular resolution + size = 100 // image canvas covers [-size..+size] + nframes = 64 // number of animation frames + delay = 8 // delay between frames in 10ms units + ) + freq := rand.Float64() * 3.0 // relative frequency of y oscillator + anim := gif.GIF{LoopCount: nframes} + phase := 0.0 // phase difference + for i := 0; i < nframes; i++ { + rect := image.Rect(0, 0, 2*size+1, 2*size+1) + img := image.NewPaletted(rect, palette) + for t := 0.0; t < cycles*2*math.Pi; t += res { + x := math.Sin(t) + y := math.Sin(t*freq + phase) + img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), + blackIndex) + } + phase += 0.1 + anim.Delay = append(anim.Delay, delay) + anim.Image = append(anim.Image, img) + } + gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors +} diff --git a/ch1/lissajous/1_6.go b/ch1/lissajous/1_6.go new file mode 100644 index 0000000..a9b2170 --- /dev/null +++ b/ch1/lissajous/1_6.go @@ -0,0 +1,65 @@ +package main + +import ( + "image" + "image/color" + "image/gif" + "io" + "math" + "math/rand" + "os" +) + +import ( + "log" + "net/http" + "time" +) + +var palette = []color.Color{ + color.Black, + color.RGBA{0xff, 0x00, 0x00, 0xff}, + color.RGBA{0x00, 0xff, 0x00, 0xff}, + color.RGBA{0x00, 0x00, 0xff, 0xff}, +} + +func main() { + rand.Seed(time.Now().UTC().UnixNano()) + + if len(os.Args) > 1 && os.Args[1] == "web" { + handler := func(w http.ResponseWriter, r *http.Request) { + lissajous(w) + } + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe("localhost:8000", nil)) + return + } + lissajous(os.Stdout) +} + +func lissajous(out io.Writer) { + const ( + cycles = 5 // number of complete x oscillator revolutions + res = 0.001 // angular resolution + size = 100 // image canvas covers [-size..+size] + nframes = 64 // number of animation frames + delay = 8 // delay between frames in 10ms units + ) + freq := rand.Float64() * 3.0 // relative frequency of y oscillator + anim := gif.GIF{LoopCount: nframes} + phase := 0.0 // phase difference + for i := 0; i < nframes; i++ { + rect := image.Rect(0, 0, 2*size+1, 2*size+1) + img := image.NewPaletted(rect, palette) + for t := 0.0; t < cycles*2*math.Pi; t += res { + x := math.Sin(t) + y := math.Sin(t*freq + phase) + img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), + uint8(rand.Intn(3))) + } + phase += 0.1 + anim.Delay = append(anim.Delay, delay) + anim.Image = append(anim.Image, img) + } + gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors +} diff --git a/ch1/lissajous/lissajous.go b/ch1/lissajous/lissajous.go new file mode 100644 index 0000000..e812912 --- /dev/null +++ b/ch1/lissajous/lissajous.go @@ -0,0 +1,68 @@ +package main + +import ( + "image" + "image/color" + "image/gif" + "io" + "math" + "math/rand" + "os" +) + +import ( + "log" + "net/http" + "time" +) + +var palette = []color.Color{ + color.Black, + color.RGBA{0x00, 0xff, 0x00, 0xff}, +} + +const ( + whiteIndex = 0 // first color in palette + blackIndex = 1 // next color in palette +) + +func main() { + rand.Seed(time.Now().UTC().UnixNano()) + + if len(os.Args) > 1 && os.Args[1] == "web" { + handler := func(w http.ResponseWriter, r *http.Request) { + lissajous(w) + } + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe("localhost:8000", nil)) + return + } + lissajous(os.Stdout) +} + +func lissajous(out io.Writer) { + const ( + cycles = 5 // number of complete x oscillator revolutions + res = 0.001 // angular resolution + size = 100 // image canvas covers [-size..+size] + nframes = 64 // number of animation frames + delay = 8 // delay between frames in 10ms units + ) + freq := rand.Float64() * 3.0 // relative frequency of y oscillator + anim := gif.GIF{LoopCount: nframes} + phase := 0.0 // phase difference + for i := 0; i < nframes; i++ { + rect := image.Rect(0, 0, 2*size+1, 2*size+1) + img := image.NewPaletted(rect, palette) + for t := 0.0; t < cycles*2*math.Pi; t += res { + x := math.Sin(t) + y := math.Sin(t*freq + phase) + img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), + blackIndex) + } + phase += 0.1 + anim.Delay = append(anim.Delay, delay) + anim.Image = append(anim.Image, img) + } + gif.EncodeAll(out, &anim) // NOTE: ignoring encoding errors +}