-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjulia.go
105 lines (90 loc) · 2.06 KB
/
julia.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//Package julia provides interface to draw a julia set with customize complementary sets and color map.
package julia
import (
"image"
"image/jpeg"
"image/png"
"math/cmplx"
"os"
)
// GenFunc defines a func type used by julia set.
type GenFunc func(complex128) complex128
type julia struct {
// h, w is the image height and width in pixels.
h, w int
// x and y represent the range of values for the real and imaginary parts.
x, y float64
// maxz defines the maximum length of a complex number.
maxz float64
fn GenFunc
// iter indicates the maximum number of iterations.
iter int
img *image.RGBA
}
// NewJulia returns a julia struct.
func NewJulia(h, w int, x, y float64, iter int, z float64, fn GenFunc) *julia {
return &julia{
h: h,
w: w,
x: x,
y: y,
fn: fn,
iter: iter,
maxz: z,
img: image.NewRGBA(image.Rect(0, 0, h, w)),
}
}
// CleanImage clean the image and create a new RGBA object.
func (j *julia) CleanImage() {
j.img = nil
j.img = image.NewRGBA(image.Rect(0, 0, j.h, j.w))
}
// Generative draws the julia set with specified color map.
func (j *julia) Generative(cm ColorMap) {
n := len(cm)
if n > 255 {
n = 255
}
for i := 0; i <= j.w; i++ {
for k := 0; k <= j.h; k++ {
nit := 0
z := complex(float64(i)/float64(j.w)*2.0*j.x-j.x, float64(k)/float64(j.h)*2.0*j.y-j.y)
for cmplx.Abs(z) <= j.maxz && nit < j.iter {
z = j.fn(z)
nit += 1
}
idx := uint8(nit*255/j.iter) % uint8(n)
j.img.Set(i, k, cm[idx])
}
}
}
// ToPng saves the image to local with PNG format.
func (j *julia) ToPng(path string) error {
f, err := os.Create(path)
if err != nil {
return err
}
if err := png.Encode(f, j.img); err != nil {
f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}
// ToJpeg saves the image to local with Jpeg format.
func (j *julia) ToJpeg(path string) error {
f, err := os.Create(path)
if err != nil {
return err
}
if err := jpeg.Encode(f, j.img, nil); err != nil {
f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
return nil
}