-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
120 lines (106 loc) · 2.85 KB
/
utils.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
package sim1
import (
"golang.org/x/image/font"
"golang.org/x/image/font/gofont/gomono"
"golang.org/x/image/font/opentype"
"golang.org/x/image/math/fixed"
"image"
"image/draw"
"image/png"
"math"
"os"
"strings"
)
func isPerfectSquare[T int | uint](n T) bool {
root := T(math.Sqrt(float64(n)))
return root*root == n
}
func PlotPNG(grid *Grid, txt string, outFile string) {
const FontDPI = 72
const FontSize = 16
txtLines := strings.Count(txt, "\n")
if len(txt) > 0 && !strings.HasSuffix(txt, "\n") {
txtLines++
}
//plotBounds := image.Rect(0, 0, int(SimSize*PlotRes), int(SimSize*PlotRes))
//plot := image.NewRGBA(plotBounds)
//draw.Draw(plot, plot.Rect, image.White, image.Point{}, draw.Over)
//
//// agents
//for i := range population {
// draw.Draw(plot,
// image.Rect(
// int(population[i].X)*PlotRes,
// int(population[i].Y)*PlotRes,
// int(population[i].X)*PlotRes+PlotRes,
// int(population[i].Y)*PlotRes+PlotRes,
// ),
// image.NewUniform(color.RGBA{
// R: uint8(population[i].Genes & GeneMaskColor & 0xFF0000 >> 16),
// G: uint8(population[i].Genes & GeneMaskColor & 0x00FF00 >> 8),
// B: uint8(population[i].Genes & GeneMaskColor & 0x0000FF),
// A: 255,
// }),
// image.Point{},
// draw.Over,
// )
//}
// output
out := image.NewRGBA(image.Rectangle{
Max: image.Point{
X: grid.Bounds().Max.X + 10,
Y: grid.Bounds().Max.Y + FontSize*(txtLines+1) + 10,
},
})
// background
draw.Draw(out, out.Rect, image.White, image.Point{}, draw.Over)
// text
f, err := opentype.Parse(gomono.TTF)
if err != nil {
panic(err)
}
face, err := opentype.NewFace(f, &opentype.FaceOptions{
Size: FontSize,
DPI: FontDPI,
Hinting: font.HintingNone,
})
if err != nil {
panic(err)
}
lines := strings.Split(txt, "\n")
for i := range lines {
(&font.Drawer{
Dst: out,
Src: image.Black,
Face: face,
Dot: fixed.Point26_6{X: 4 * FontDPI, Y: fixed.Int26_6((FontSize*FontDPI + FontSize) * (i + 1))},
}).DrawString(lines[i])
}
//// plot border
//bPlot := image.NewRGBA(image.Rectangle{Max: plot.Rect.Max.Add(image.Point{X: 2, Y: 2})})
//draw.Draw(bPlot, bPlot.Rect, image.Black, image.Point{}, draw.Over)
//draw.Draw(bPlot, image.Rectangle{Min: image.Point{X: 1, Y: 1}, Max: bPlot.Rect.Max}, plot, image.Point{}, draw.Over)
//
//// add plot
//draw.Draw(out, image.Rectangle{
// Min: image.Point{X: 4, Y: out.Rect.Max.Y - bPlot.Rect.Max.Y - 4},
// Max: out.Rect.Max,
//}, bPlot, image.Point{}, draw.Over)
draw.Draw(out, image.Rectangle{
Min: image.Point{X: 4, Y: out.Rect.Max.Y - grid.Bounds().Max.Y - 4},
Max: out.Rect.Max,
}, grid, image.Point{}, draw.Over)
// save to file
file, err := os.OpenFile(outFile, os.O_CREATE|os.O_RDWR, 0755)
if err != nil {
panic(err)
}
err = png.Encode(file, out)
if err != nil {
panic(err)
}
err = file.Close()
if err != nil {
panic(err)
}
}