summaryrefslogtreecommitdiff
path: root/lissajous.go
diff options
context:
space:
mode:
Diffstat (limited to 'lissajous.go')
-rw-r--r--lissajous.go61
1 files changed, 61 insertions, 0 deletions
diff --git a/lissajous.go b/lissajous.go
new file mode 100644
index 0000000..1d1ad70
--- /dev/null
+++ b/lissajous.go
@@ -0,0 +1,61 @@
+package lissajous
+
+import (
+ "image"
+ "image/color"
+ "image/gif"
+ "io"
+ "math"
+ "math/rand/v2"
+)
+
+var palette = []color.Color{
+ color.Black,
+ color.RGBA{0x00, 0xff, 0x00, 0xff},
+ color.RGBA{0xff, 0x00, 0x00, 0xff},
+ color.RGBA{0x00, 0x00, 0xff, 0xff},
+}
+
+const (
+ backgroundIndex = iota
+ foregroundIndex
+)
+
+func Lissajous(out io.Writer) {
+ const (
+ cycles = 5
+ res = 0.001
+ size = 100
+ nframes = 64
+ delay = 8
+ )
+
+ // Note that this generates the exact same random number per
+ // run of the program.
+ freq := rand.Float64() * 3.0
+ anim := gif.GIF{LoopCount: nframes}
+
+ for i := range nframes {
+ img := newImage(size, cycles, float64(i)/10, res, freq)
+
+ anim.Delay = append(anim.Delay, delay)
+ anim.Image = append(anim.Image, img)
+ }
+
+ gif.EncodeAll(out, &anim)
+}
+
+func newImage(size, cycles int, phase, res, freq float64) *image.Paletted {
+ rect := image.Rect(0, 0, 2*size+1, 2*size+1)
+ img := image.NewPaletted(rect, palette)
+
+ randIndex := 1 + uint8(rand.IntN(len(palette)-1))
+
+ for t := 0.0; t < float64(cycles)*2*math.Pi; t += res {
+ x := math.Sin(t)
+ y := math.Sin(t*freq + phase)
+ img.SetColorIndex(size+int(x*float64(size)+0.5), size+int(y*float64(size)+0.5), randIndex)
+ }
+
+ return img
+}