Skip to content

Commit 1fd6622

Browse files
committed
refactored
1 parent a205d6a commit 1fd6622

File tree

17 files changed

+380
-473
lines changed

17 files changed

+380
-473
lines changed

main.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ func main() {
9898
if Workers < 1 {
9999
Workers = runtime.NumCPU()
100100
}
101-
primitive.InitPools(Workers * 2)
102101

103102
// read input image
104103
primitive.Log(1, "reading %s\n", Input)
@@ -118,13 +117,13 @@ func main() {
118117
}
119118

120119
// run algorithm
121-
model := primitive.NewModel(input, bg, OutputSize)
120+
model := primitive.NewModel(input, bg, OutputSize, Workers)
122121
primitive.Log(1, "%d: t=%.3f, score=%.6f\n", 0, 0.0, model.Score)
123122
start := time.Now()
124123
for i := 1; i <= Number; i++ {
125124
// find optimal shape and add it to the model
126125
t := time.Now()
127-
n := model.Step(primitive.ShapeType(Mode), Alpha, Workers)
126+
n := model.Step(primitive.ShapeType(Mode), Alpha)
128127
nps := primitive.NumberString(float64(n) / time.Since(t).Seconds())
129128
elapsed := time.Since(start).Seconds()
130129
primitive.Log(1, "%d: t=%.3f, score=%.6f, n=%d, n/s=%s\n", i, elapsed, model.Score, n, nps)
@@ -133,7 +132,7 @@ func main() {
133132
for _, output := range Outputs {
134133
ext := strings.ToLower(filepath.Ext(output))
135134
saveFrames := strings.Contains(output, "%") && ext != ".gif"
136-
saveFrames = saveFrames && i%10 == 0
135+
// saveFrames = saveFrames && i%10 == 0
137136
if saveFrames || i == Number {
138137
path := output
139138
if saveFrames {

primitive/core.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package primitive
2+
3+
import (
4+
"image"
5+
"math"
6+
)
7+
8+
func computeColor(target, current *image.RGBA, lines []Scanline, alpha int) Color {
9+
var rsum, gsum, bsum, count int64
10+
a := 0x101 * 255 / alpha
11+
for _, line := range lines {
12+
i := target.PixOffset(line.X1, line.Y)
13+
for x := line.X1; x <= line.X2; x++ {
14+
tr := int(target.Pix[i])
15+
tg := int(target.Pix[i+1])
16+
tb := int(target.Pix[i+2])
17+
cr := int(current.Pix[i])
18+
cg := int(current.Pix[i+1])
19+
cb := int(current.Pix[i+2])
20+
i += 4
21+
rsum += int64((tr-cr)*a + cr*0x101)
22+
gsum += int64((tg-cg)*a + cg*0x101)
23+
bsum += int64((tb-cb)*a + cb*0x101)
24+
count++
25+
}
26+
}
27+
if count == 0 {
28+
return Color{}
29+
}
30+
r := clampInt(int(rsum/count)>>8, 0, 255)
31+
g := clampInt(int(gsum/count)>>8, 0, 255)
32+
b := clampInt(int(bsum/count)>>8, 0, 255)
33+
return Color{r, g, b, alpha}
34+
}
35+
36+
func copyLines(dst, src *image.RGBA, lines []Scanline) {
37+
for _, line := range lines {
38+
a := dst.PixOffset(line.X1, line.Y)
39+
b := a + (line.X2-line.X1+1)*4
40+
copy(dst.Pix[a:b], src.Pix[a:b])
41+
}
42+
}
43+
44+
func drawLines(im *image.RGBA, c Color, lines []Scanline) {
45+
const m = 0xffff
46+
sr, sg, sb, sa := c.NRGBA().RGBA()
47+
for _, line := range lines {
48+
ma := line.Alpha
49+
a := (m - sa*ma/m) * 0x101
50+
i := im.PixOffset(line.X1, line.Y)
51+
for x := line.X1; x <= line.X2; x++ {
52+
dr := uint32(im.Pix[i+0])
53+
dg := uint32(im.Pix[i+1])
54+
db := uint32(im.Pix[i+2])
55+
da := uint32(im.Pix[i+3])
56+
im.Pix[i+0] = uint8((dr*a + sr*ma) / m >> 8)
57+
im.Pix[i+1] = uint8((dg*a + sg*ma) / m >> 8)
58+
im.Pix[i+2] = uint8((db*a + sb*ma) / m >> 8)
59+
im.Pix[i+3] = uint8((da*a + sa*ma) / m >> 8)
60+
i += 4
61+
}
62+
}
63+
}
64+
65+
func differenceFull(a, b *image.RGBA) float64 {
66+
size := a.Bounds().Size()
67+
w, h := size.X, size.Y
68+
var total uint64
69+
for y := 0; y < h; y++ {
70+
i := a.PixOffset(0, y)
71+
for x := 0; x < w; x++ {
72+
ar := int(a.Pix[i])
73+
ag := int(a.Pix[i+1])
74+
ab := int(a.Pix[i+2])
75+
br := int(b.Pix[i])
76+
bg := int(b.Pix[i+1])
77+
bb := int(b.Pix[i+2])
78+
i += 4
79+
dr := ar - br
80+
dg := ag - bg
81+
db := ab - bb
82+
total += uint64(dr*dr + dg*dg + db*db)
83+
}
84+
}
85+
return math.Sqrt(float64(total)/float64(w*h*3)) / 255
86+
}
87+
88+
func differencePartial(target, before, after *image.RGBA, score float64, lines []Scanline) float64 {
89+
size := target.Bounds().Size()
90+
w, h := size.X, size.Y
91+
total := uint64(math.Pow(score*255, 2) * float64(w*h*3))
92+
for _, line := range lines {
93+
i := target.PixOffset(line.X1, line.Y)
94+
for x := line.X1; x <= line.X2; x++ {
95+
tr := int(target.Pix[i])
96+
tg := int(target.Pix[i+1])
97+
tb := int(target.Pix[i+2])
98+
br := int(before.Pix[i])
99+
bg := int(before.Pix[i+1])
100+
bb := int(before.Pix[i+2])
101+
ar := int(after.Pix[i])
102+
ag := int(after.Pix[i+1])
103+
ab := int(after.Pix[i+2])
104+
i += 4
105+
dr1 := tr - br
106+
dg1 := tg - bg
107+
db1 := tb - bb
108+
dr2 := tr - ar
109+
dg2 := tg - ag
110+
db2 := tb - ab
111+
total -= uint64(dr1*dr1 + dg1*dg1 + db1*db1)
112+
total += uint64(dr2*dr2 + dg2*dg2 + db2*db2)
113+
}
114+
}
115+
return math.Sqrt(float64(total)/float64(w*h*3)) / 255
116+
}

primitive/difference.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

primitive/draw.go

Lines changed: 0 additions & 32 deletions
This file was deleted.

primitive/ellipse.go

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,32 @@ package primitive
33
import (
44
"fmt"
55
"math"
6-
"math/rand"
76

87
"github.com/fogleman/gg"
98
)
109

1110
type Ellipse struct {
12-
W, H int
11+
Worker *Worker
1312
X, Y int
1413
Rx, Ry int
1514
Circle bool
1615
}
1716

18-
func NewRandomEllipse(w, h int, rnd *rand.Rand) *Ellipse {
19-
x := rnd.Intn(w)
20-
y := rnd.Intn(h)
17+
func NewRandomEllipse(worker *Worker) *Ellipse {
18+
rnd := worker.Rnd
19+
x := rnd.Intn(worker.W)
20+
y := rnd.Intn(worker.H)
2121
rx := rnd.Intn(32) + 1
2222
ry := rnd.Intn(32) + 1
23-
return &Ellipse{w, h, x, y, rx, ry, false}
23+
return &Ellipse{worker, x, y, rx, ry, false}
2424
}
2525

26-
func NewRandomCircle(w, h int, rnd *rand.Rand) *Ellipse {
27-
x := rnd.Intn(w)
28-
y := rnd.Intn(h)
26+
func NewRandomCircle(worker *Worker) *Ellipse {
27+
rnd := worker.Rnd
28+
x := rnd.Intn(worker.W)
29+
y := rnd.Intn(worker.H)
2930
r := rnd.Intn(32) + 1
30-
return &Ellipse{w, h, x, y, r, r, true}
31+
return &Ellipse{worker, x, y, r, r, true}
3132
}
3233

3334
func (c *Ellipse) Draw(dc *gg.Context, scale float64) {
@@ -46,46 +47,51 @@ func (c *Ellipse) Copy() Shape {
4647
return &a
4748
}
4849

49-
func (c *Ellipse) Mutate(rnd *rand.Rand) {
50+
func (c *Ellipse) Mutate() {
51+
w := c.Worker.W
52+
h := c.Worker.H
53+
rnd := c.Worker.Rnd
5054
switch rnd.Intn(3) {
5155
case 0:
52-
c.X = clampInt(c.X+rnd.Intn(21)-10, 0, c.W-1)
53-
c.Y = clampInt(c.Y+rnd.Intn(21)-10, 0, c.H-1)
56+
c.X = clampInt(c.X+rnd.Intn(21)-10, 0, w-1)
57+
c.Y = clampInt(c.Y+rnd.Intn(21)-10, 0, h-1)
5458
case 1:
55-
c.Rx = clampInt(c.Rx+rnd.Intn(21)-10, 1, c.W-1)
59+
c.Rx = clampInt(c.Rx+rnd.Intn(21)-10, 1, w-1)
5660
if c.Circle {
5761
c.Ry = c.Rx
5862
}
5963
case 2:
60-
c.Ry = clampInt(c.Ry+rnd.Intn(21)-10, 1, c.W-1)
64+
c.Ry = clampInt(c.Ry+rnd.Intn(21)-10, 1, w-1)
6165
if c.Circle {
6266
c.Rx = c.Ry
6367
}
6468
}
6569
}
6670

67-
func (c *Ellipse) Rasterize(buf []Scanline) []Scanline {
68-
lines := make([]Scanline, 0, c.Ry*2)
71+
func (c *Ellipse) Rasterize() []Scanline {
72+
w := c.Worker.W
73+
h := c.Worker.H
74+
lines := c.Worker.Lines[:0]
6975
aspect := float64(c.Rx) / float64(c.Ry)
7076
for dy := 0; dy < c.Ry; dy++ {
7177
y1 := c.Y - dy
7278
y2 := c.Y + dy
73-
if (y1 < 0 || y1 >= c.H) && (y2 < 0 || y2 >= c.H) {
79+
if (y1 < 0 || y1 >= h) && (y2 < 0 || y2 >= h) {
7480
continue
7581
}
76-
w := int(math.Sqrt(float64(c.Ry*c.Ry-dy*dy)) * aspect)
77-
x1 := c.X - w
78-
x2 := c.X + w
82+
s := int(math.Sqrt(float64(c.Ry*c.Ry-dy*dy)) * aspect)
83+
x1 := c.X - s
84+
x2 := c.X + s
7985
if x1 < 0 {
8086
x1 = 0
8187
}
82-
if x2 >= c.W {
83-
x2 = c.W - 1
88+
if x2 >= w {
89+
x2 = w - 1
8490
}
85-
if y1 >= 0 && y1 < c.H {
91+
if y1 >= 0 && y1 < h {
8692
lines = append(lines, Scanline{y1, x1, x2, 0xffff})
8793
}
88-
if y2 >= 0 && y2 < c.H && dy > 0 {
94+
if y2 >= 0 && y2 < h && dy > 0 {
8995
lines = append(lines, Scanline{y2, x1, x2, 0xffff})
9096
}
9197
}

primitive/functions.go

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)