-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
161 lines (142 loc) · 3.62 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"image"
"image/color"
"image/png"
"math"
"math/rand"
"os"
"time"
)
const (
imagePath = "voronoi.png"
imageWidth = 800
imageHeight = 600
seedCount = 20 // number of points in the image with an associated color
seedRadius = 3 // number of pixels of the radius
)
type Circle struct {
p image.Point
r int
}
// IsInside returns true if point p is inside the circle
func (c Circle) IsInside(p image.Point) bool {
dx := float64(c.p.X - p.X)
dy := float64(c.p.Y - p.Y)
dist := math.Sqrt(dx*dx + dy*dy)
if dist <= float64(c.r) {
return true
}
return false
}
// Dist returns the distance between the point p and the circle
func (c Circle) Dist(p image.Point) float64 {
// distance to the center - radius
dx := float64(c.p.X - p.X)
dy := float64(c.p.Y - p.Y)
dist := math.Sqrt(dx*dx+dy*dy) - float64(c.r)
return dist
}
// Draw draws a circle in the img with the specified color
func (c Circle) Draw(img image.RGBA, color color.Color) {
pUpLeft := image.Point{
c.p.X - c.r,
c.p.Y - c.r,
}
pDownRight := image.Point{
c.p.X + c.r,
c.p.Y + c.r,
}
// we create a rectagle around the central point of the
// circle so we only check these pixels instead
// checking the pixels of all the image
outerRectangle := image.Rectangle{
pUpLeft,
pDownRight,
}
for x := outerRectangle.Min.X; x <= outerRectangle.Max.X; x++ {
for y := outerRectangle.Min.Y; y <= outerRectangle.Max.Y; y++ {
pixel := image.Point{x, y}
if c.IsInside(pixel) {
img.Set(pixel.X, pixel.Y, color)
}
}
}
}
type Seed struct {
Circle
color color.Color
}
var COLOR_SEED = color.Black
var colorList = []color.RGBA{
{0, 255, 255, 255}, // "Aqua"
{0, 0, 255, 255}, // "Blue"
{255, 0, 255, 255}, // "Fuchsia"
{0, 255, 0, 255}, // "Lime"
{255, 255, 0, 255}, // "Yellow"
{0, 128, 128, 255}, // "Teal"
{192, 192, 192, 255}, // "Silver"
{128, 128, 128, 255}, // "Gray"
{0, 128, 0, 255}, // "Green"
{0, 0, 128, 255}, // "Navy"
{128, 0, 0, 255}, // "Maroon"
{128, 128, 0, 255}, // "Olive"
{128, 0, 128, 255}, // "Purple"
{255, 0, 0, 255}, // "Red"
{255, 255, 255, 255}, // "White"
{255, 165, 0, 255}, // "Orange"
{0, 250, 154, 255}, // "MediumSpringGreen"
{255, 215, 0, 255}, // "Gold"
{255, 127, 80, 255}, // "Coral"
{220, 20, 60, 255}, // "Crimson"
}
// getClosestSeed returns the closest seed to point p
func getClosestSeed(p image.Point, seeds []Seed) Seed {
currentDist := math.MaxFloat64
closestSeed := seeds[0]
for _, seed := range seeds {
dist := seed.Dist(p)
if dist < currentDist {
closestSeed = seed
currentDist = dist
}
}
return closestSeed
}
func main() {
// define the size of the image
upLeft := image.Point{0, 0}
lowRight := image.Point{imageWidth, imageHeight}
// create new png image
img := image.NewRGBA(image.Rectangle{upLeft, lowRight})
// generate the seed points
randomSeed := rand.NewSource(time.Now().UnixNano())
random := rand.New(randomSeed)
seeds := make([]Seed, seedCount)
for i := 0; i < seedCount; i++ {
c := Circle{
image.Point{
X: random.Intn(imageWidth-seedRadius) + seedRadius,
Y: random.Intn(imageHeight-seedRadius) + seedRadius,
},
seedRadius,
}
seeds[i] = Seed{c, colorList[i%len(colorList)]}
}
// for each pixel in the image, get the closest seed
// and set its color
for x := 0; x < imageWidth; x++ {
for y := 0; y < imageHeight; y++ {
p := image.Point{x, y}
seed := getClosestSeed(p, seeds)
img.Set(x, y, seed.color)
}
}
// draw the seeds
for _, seed := range seeds {
seed.Circle.Draw(*img, COLOR_SEED)
}
// save image as png
f, _ := os.Create(imagePath)
png.Encode(f, img)
}