Skip to content

Instantly share code, notes, and snippets.

@djpnewton
Created October 26, 2011 05:01
Show Gist options
  • Save djpnewton/1315488 to your computer and use it in GitHub Desktop.
Save djpnewton/1315488 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"flag"
"image"
"image/png"
"math"
"os"
)
// generate a value for a wave (with orientation theta) at point x,y
func wave(x float64, y float64, theta float64, stripes float64, size float64, offset float64) float64 {
cth := math.Cos(theta)
sth := math.Sin(theta)
scale := 2 * math.Pi * stripes / size
return (math.Cos((cth * x + sth * y) * scale + offset) + 1) / 2
}
func main() {
_k := flag.Int("k", 4, "The number of waves traveling in different directions")
_stripes := flag.Int("stripes", 25, "The number of stripes per wave")
size := flag.Int("size", 800, "The image size in pixels")
log := flag.Bool("log", false, "Whether to stretch the image in a log-polar fashion")
_offset := flag.Float64("offset", 0, "Offset (make the wave travel)")
steps := flag.Int("steps", 1, "How many steps to the offset")
nice := flag.Bool("nice", true, "Make a nice plasma effect")
hard := flag.Bool("hard", false, "Filter a high contrast hard edge on the pattern")
flag.Parse()
k := float64(*_k)
stripes := float64(*_stripes)
img := image.NewRGBA(*size, *size)
for step := 1; step <= *steps; step++ {
offset := (*_offset) * float64(step) / float64(*steps)
for i := 0; i < *size; i++ {
for j := 0; j < *size; j++ {
// cartesian coordinates
x := float64(j - *size / 2)
y := float64(i - *size / 2)
// log-polar coordinates
theta := math.Atan2(y, x)
r := math.Log(math.Sqrt(x * x + y * y))
C := 0.0 // accumulator
for t := 0.0; t < math.Pi; t += math.Pi / float64(k) {
if *log {
C += math.Cos((theta * math.Cos(t) + r * math.Sin(t)) * stripes )
} else {
C += wave(x, y, t, stripes, float64(*size), offset)
}
}
// convert result to 0-255 range
c := uint8(0)
if *nice {
v := math.Fmod(C, 1)
_k := C - v
if int(_k) & 1 == 0 {
c = uint8(v * 255)
} else {
c = uint8((1 - v) * 255)
}
} else {
c = uint8((C + k) / (k * 2) * 255)
}
// create a hard edge
if *hard {
if c > 128 {
c = 255
} else {
c = 0
}
}
img.Set(i, j, image.RGBAColor{c, c, c, 255})
}
}
file, _ := os.Create(fmt.Sprintf("test%d.png", step))
png.Encode(file, img)
file.Close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment