This repository has been archived by the owner on May 2, 2018. It is now read-only.
/
main.go
88 lines (77 loc) · 1.8 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package main
import (
"fmt"
"image"
"image/color"
"math/cmplx"
"sync"
"github.com/disintegration/imaging"
)
const (
maxIterations = 50
size = 1024
animate = true
)
func mandelbrot(z, c complex128) complex128 {
return z*z + c
}
func iteration(c complex128, iterations int) int {
var z complex128
for i := 0; i < iterations; i++ {
z = mandelbrot(z, c)
r, _ := cmplx.Polar(z)
if r >= 2 {
return i
}
}
return 0
}
func colorCode(iteration, iterations int) color.Color {
shade := uint8(float64(iteration) / float64(iterations) * 255)
return color.NRGBA{shade, shade, shade, 255}
}
func pixelToReal(w, h, x, y int, offsetX, offsetY, zoom float64) (float64, float64) {
rx := ((float64(x)/float64(w)+offsetX)*3 - 2) / zoom
ry := ((float64(y)/float64(h)+offsetY)*3 - 1.5) / zoom
return rx, ry
}
func fractal(w, h int, offsetX, offsetY, zoom float64, iterations int) image.Image {
img := imaging.New(w, h, color.White)
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
sx, sy := pixelToReal(w, h, x, y, offsetX, offsetY, zoom)
j := complex(sx, sy)
i := iteration(j, iterations)
c := colorCode(i, iterations)
img.Set(x, y, c)
}
}
return img
}
func main() {
const zoom = 1.0
const x, y = 0.0, 0.0
img := fractal(size, size, x, y, zoom, maxIterations)
imaging.Save(img, fmt.Sprintf("%.3f_%.3f_%.3f.png", x, y, zoom))
if !animate {
return
}
var wg sync.WaitGroup
is := make(chan int)
for procs := 0; procs < 4; procs++ {
wg.Add(1)
go func(is chan int) {
defer wg.Done()
for i := range is {
frame := fractal(size, size, x-0.03*float64(i), y-0.006*float64(i), zoom+0.12*float64(i), maxIterations)
imaging.Save(frame, fmt.Sprintf("frames/frame_%04d.png", i))
println(i)
}
}(is)
}
for i := 0; i < 1500; i++ {
is <- i
}
close(is)
wg.Wait()
}