From 273b48a8b409126e14f8beb23cee4255d1f08a2c Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Fri, 19 Oct 2018 06:24:23 -0700 Subject: GOPROXY means we can avoid vendoring --- vendor/github.com/fogleman/primitive/LICENSE.md | 19 -- .../fogleman/primitive/primitive/color.go | 44 ----- .../fogleman/primitive/primitive/core.go | 124 ------------- .../fogleman/primitive/primitive/ellipse.go | 179 ------------------- .../fogleman/primitive/primitive/heatmap.go | 59 ------ .../github.com/fogleman/primitive/primitive/log.go | 23 --- .../fogleman/primitive/primitive/model.go | 174 ------------------ .../fogleman/primitive/primitive/optimize.go | 75 -------- .../fogleman/primitive/primitive/polygon.go | 122 ------------- .../fogleman/primitive/primitive/quadratic.go | 100 ----------- .../fogleman/primitive/primitive/raster.go | 46 ----- .../fogleman/primitive/primitive/rectangle.go | 198 --------------------- .../fogleman/primitive/primitive/scanline.go | 29 --- .../fogleman/primitive/primitive/shape.go | 25 --- .../fogleman/primitive/primitive/state.go | 48 ----- .../fogleman/primitive/primitive/triangle.go | 171 ------------------ .../fogleman/primitive/primitive/util.go | 195 -------------------- .../fogleman/primitive/primitive/worker.go | 108 ----------- 18 files changed, 1739 deletions(-) delete mode 100644 vendor/github.com/fogleman/primitive/LICENSE.md delete mode 100644 vendor/github.com/fogleman/primitive/primitive/color.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/core.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/ellipse.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/heatmap.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/log.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/model.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/optimize.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/polygon.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/quadratic.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/raster.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/rectangle.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/scanline.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/shape.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/state.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/triangle.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/util.go delete mode 100644 vendor/github.com/fogleman/primitive/primitive/worker.go (limited to 'vendor/github.com/fogleman/primitive') diff --git a/vendor/github.com/fogleman/primitive/LICENSE.md b/vendor/github.com/fogleman/primitive/LICENSE.md deleted file mode 100644 index d7b4099..0000000 --- a/vendor/github.com/fogleman/primitive/LICENSE.md +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2016 Michael Fogleman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/fogleman/primitive/primitive/color.go b/vendor/github.com/fogleman/primitive/primitive/color.go deleted file mode 100644 index 2828957..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/color.go +++ /dev/null @@ -1,44 +0,0 @@ -package primitive - -import ( - "fmt" - "image/color" - "strings" -) - -type Color struct { - R, G, B, A int -} - -func MakeColor(c color.Color) Color { - r, g, b, a := c.RGBA() - return Color{int(r / 257), int(g / 257), int(b / 257), int(a / 257)} -} - -func MakeHexColor(x string) Color { - x = strings.Trim(x, "#") - var r, g, b, a int - a = 255 - switch len(x) { - case 3: - fmt.Sscanf(x, "%1x%1x%1x", &r, &g, &b) - r = (r << 4) | r - g = (g << 4) | g - b = (b << 4) | b - case 4: - fmt.Sscanf(x, "%1x%1x%1x%1x", &r, &g, &b, &a) - r = (r << 4) | r - g = (g << 4) | g - b = (b << 4) | b - a = (a << 4) | a - case 6: - fmt.Sscanf(x, "%02x%02x%02x", &r, &g, &b) - case 8: - fmt.Sscanf(x, "%02x%02x%02x%02x", &r, &g, &b, &a) - } - return Color{r, g, b, a} -} - -func (c *Color) NRGBA() color.NRGBA { - return color.NRGBA{uint8(c.R), uint8(c.G), uint8(c.B), uint8(c.A)} -} diff --git a/vendor/github.com/fogleman/primitive/primitive/core.go b/vendor/github.com/fogleman/primitive/primitive/core.go deleted file mode 100644 index 5a0c0aa..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/core.go +++ /dev/null @@ -1,124 +0,0 @@ -package primitive - -import ( - "image" - "math" -) - -func computeColor(target, current *image.RGBA, lines []Scanline, alpha int) Color { - var rsum, gsum, bsum, count int64 - a := 0x101 * 255 / alpha - for _, line := range lines { - i := target.PixOffset(line.X1, line.Y) - for x := line.X1; x <= line.X2; x++ { - tr := int(target.Pix[i]) - tg := int(target.Pix[i+1]) - tb := int(target.Pix[i+2]) - cr := int(current.Pix[i]) - cg := int(current.Pix[i+1]) - cb := int(current.Pix[i+2]) - i += 4 - rsum += int64((tr-cr)*a + cr*0x101) - gsum += int64((tg-cg)*a + cg*0x101) - bsum += int64((tb-cb)*a + cb*0x101) - count++ - } - } - if count == 0 { - return Color{} - } - r := clampInt(int(rsum/count)>>8, 0, 255) - g := clampInt(int(gsum/count)>>8, 0, 255) - b := clampInt(int(bsum/count)>>8, 0, 255) - return Color{r, g, b, alpha} -} - -func copyLines(dst, src *image.RGBA, lines []Scanline) { - for _, line := range lines { - a := dst.PixOffset(line.X1, line.Y) - b := a + (line.X2-line.X1+1)*4 - copy(dst.Pix[a:b], src.Pix[a:b]) - } -} - -func drawLines(im *image.RGBA, c Color, lines []Scanline) { - const m = 0xffff - sr, sg, sb, sa := c.NRGBA().RGBA() - for _, line := range lines { - ma := line.Alpha - a := (m - sa*ma/m) * 0x101 - i := im.PixOffset(line.X1, line.Y) - for x := line.X1; x <= line.X2; x++ { - dr := uint32(im.Pix[i+0]) - dg := uint32(im.Pix[i+1]) - db := uint32(im.Pix[i+2]) - da := uint32(im.Pix[i+3]) - im.Pix[i+0] = uint8((dr*a + sr*ma) / m >> 8) - im.Pix[i+1] = uint8((dg*a + sg*ma) / m >> 8) - im.Pix[i+2] = uint8((db*a + sb*ma) / m >> 8) - im.Pix[i+3] = uint8((da*a + sa*ma) / m >> 8) - i += 4 - } - } -} - -func differenceFull(a, b *image.RGBA) float64 { - size := a.Bounds().Size() - w, h := size.X, size.Y - var total uint64 - for y := 0; y < h; y++ { - i := a.PixOffset(0, y) - for x := 0; x < w; x++ { - ar := int(a.Pix[i]) - ag := int(a.Pix[i+1]) - ab := int(a.Pix[i+2]) - aa := int(a.Pix[i+3]) - br := int(b.Pix[i]) - bg := int(b.Pix[i+1]) - bb := int(b.Pix[i+2]) - ba := int(b.Pix[i+3]) - i += 4 - dr := ar - br - dg := ag - bg - db := ab - bb - da := aa - ba - total += uint64(dr*dr + dg*dg + db*db + da*da) - } - } - return math.Sqrt(float64(total)/float64(w*h*4)) / 255 -} - -func differencePartial(target, before, after *image.RGBA, score float64, lines []Scanline) float64 { - size := target.Bounds().Size() - w, h := size.X, size.Y - total := uint64(math.Pow(score*255, 2) * float64(w*h*4)) - for _, line := range lines { - i := target.PixOffset(line.X1, line.Y) - for x := line.X1; x <= line.X2; x++ { - tr := int(target.Pix[i]) - tg := int(target.Pix[i+1]) - tb := int(target.Pix[i+2]) - ta := int(target.Pix[i+3]) - br := int(before.Pix[i]) - bg := int(before.Pix[i+1]) - bb := int(before.Pix[i+2]) - ba := int(before.Pix[i+3]) - ar := int(after.Pix[i]) - ag := int(after.Pix[i+1]) - ab := int(after.Pix[i+2]) - aa := int(after.Pix[i+3]) - i += 4 - dr1 := tr - br - dg1 := tg - bg - db1 := tb - bb - da1 := ta - ba - dr2 := tr - ar - dg2 := tg - ag - db2 := tb - ab - da2 := ta - aa - total -= uint64(dr1*dr1 + dg1*dg1 + db1*db1 + da1*da1) - total += uint64(dr2*dr2 + dg2*dg2 + db2*db2 + da2*da2) - } - } - return math.Sqrt(float64(total)/float64(w*h*4)) / 255 -} diff --git a/vendor/github.com/fogleman/primitive/primitive/ellipse.go b/vendor/github.com/fogleman/primitive/primitive/ellipse.go deleted file mode 100644 index 878df40..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/ellipse.go +++ /dev/null @@ -1,179 +0,0 @@ -package primitive - -import ( - "fmt" - "math" - - "github.com/fogleman/gg" - "github.com/golang/freetype/raster" -) - -type Ellipse struct { - Worker *Worker - X, Y int - Rx, Ry int - Circle bool -} - -func NewRandomEllipse(worker *Worker) *Ellipse { - rnd := worker.Rnd - x := rnd.Intn(worker.W) - y := rnd.Intn(worker.H) - rx := rnd.Intn(32) + 1 - ry := rnd.Intn(32) + 1 - return &Ellipse{worker, x, y, rx, ry, false} -} - -func NewRandomCircle(worker *Worker) *Ellipse { - rnd := worker.Rnd - x := rnd.Intn(worker.W) - y := rnd.Intn(worker.H) - r := rnd.Intn(32) + 1 - return &Ellipse{worker, x, y, r, r, true} -} - -func (c *Ellipse) Draw(dc *gg.Context, scale float64) { - dc.DrawEllipse(float64(c.X), float64(c.Y), float64(c.Rx), float64(c.Ry)) - dc.Fill() -} - -func (c *Ellipse) SVG(attrs string) string { - return fmt.Sprintf( - "", - attrs, c.X, c.Y, c.Rx, c.Ry) -} - -func (c *Ellipse) Copy() Shape { - a := *c - return &a -} - -func (c *Ellipse) Mutate() { - w := c.Worker.W - h := c.Worker.H - rnd := c.Worker.Rnd - switch rnd.Intn(3) { - case 0: - c.X = clampInt(c.X+int(rnd.NormFloat64()*16), 0, w-1) - c.Y = clampInt(c.Y+int(rnd.NormFloat64()*16), 0, h-1) - case 1: - c.Rx = clampInt(c.Rx+int(rnd.NormFloat64()*16), 1, w-1) - if c.Circle { - c.Ry = c.Rx - } - case 2: - c.Ry = clampInt(c.Ry+int(rnd.NormFloat64()*16), 1, w-1) - if c.Circle { - c.Rx = c.Ry - } - } -} - -func (c *Ellipse) Rasterize() []Scanline { - w := c.Worker.W - h := c.Worker.H - lines := c.Worker.Lines[:0] - aspect := float64(c.Rx) / float64(c.Ry) - for dy := 0; dy < c.Ry; dy++ { - y1 := c.Y - dy - y2 := c.Y + dy - if (y1 < 0 || y1 >= h) && (y2 < 0 || y2 >= h) { - continue - } - s := int(math.Sqrt(float64(c.Ry*c.Ry-dy*dy)) * aspect) - x1 := c.X - s - x2 := c.X + s - if x1 < 0 { - x1 = 0 - } - if x2 >= w { - x2 = w - 1 - } - if y1 >= 0 && y1 < h { - lines = append(lines, Scanline{y1, x1, x2, 0xffff}) - } - if y2 >= 0 && y2 < h && dy > 0 { - lines = append(lines, Scanline{y2, x1, x2, 0xffff}) - } - } - return lines -} - -type RotatedEllipse struct { - Worker *Worker - X, Y float64 - Rx, Ry float64 - Angle float64 -} - -func NewRandomRotatedEllipse(worker *Worker) *RotatedEllipse { - rnd := worker.Rnd - x := rnd.Float64() * float64(worker.W) - y := rnd.Float64() * float64(worker.H) - rx := rnd.Float64()*32 + 1 - ry := rnd.Float64()*32 + 1 - a := rnd.Float64() * 360 - return &RotatedEllipse{worker, x, y, rx, ry, a} -} - -func (c *RotatedEllipse) Draw(dc *gg.Context, scale float64) { - dc.Push() - dc.RotateAbout(radians(c.Angle), c.X, c.Y) - dc.DrawEllipse(c.X, c.Y, c.Rx, c.Ry) - dc.Fill() - dc.Pop() -} - -func (c *RotatedEllipse) SVG(attrs string) string { - return fmt.Sprintf( - "", - c.X, c.Y, c.Angle, c.Rx, c.Ry, attrs) -} - -func (c *RotatedEllipse) Copy() Shape { - a := *c - return &a -} - -func (c *RotatedEllipse) Mutate() { - w := c.Worker.W - h := c.Worker.H - rnd := c.Worker.Rnd - switch rnd.Intn(3) { - case 0: - c.X = clamp(c.X+rnd.NormFloat64()*16, 0, float64(w-1)) - c.Y = clamp(c.Y+rnd.NormFloat64()*16, 0, float64(h-1)) - case 1: - c.Rx = clamp(c.Rx+rnd.NormFloat64()*16, 1, float64(w-1)) - c.Ry = clamp(c.Ry+rnd.NormFloat64()*16, 1, float64(w-1)) - case 2: - c.Angle = c.Angle + rnd.NormFloat64()*32 - } -} - -func (c *RotatedEllipse) Rasterize() []Scanline { - var path raster.Path - const n = 16 - for i := 0; i < n; i++ { - p1 := float64(i+0) / n - p2 := float64(i+1) / n - a1 := p1 * 2 * math.Pi - a2 := p2 * 2 * math.Pi - x0 := c.Rx * math.Cos(a1) - y0 := c.Ry * math.Sin(a1) - x1 := c.Rx * math.Cos(a1+(a2-a1)/2) - y1 := c.Ry * math.Sin(a1+(a2-a1)/2) - x2 := c.Rx * math.Cos(a2) - y2 := c.Ry * math.Sin(a2) - cx := 2*x1 - x0/2 - x2/2 - cy := 2*y1 - y0/2 - y2/2 - x0, y0 = rotate(x0, y0, radians(c.Angle)) - cx, cy = rotate(cx, cy, radians(c.Angle)) - x2, y2 = rotate(x2, y2, radians(c.Angle)) - if i == 0 { - path.Start(fixp(x0+c.X, y0+c.Y)) - } - path.Add2(fixp(cx+c.X, cy+c.Y), fixp(x2+c.X, y2+c.Y)) - } - return fillPath(c.Worker, path) -} diff --git a/vendor/github.com/fogleman/primitive/primitive/heatmap.go b/vendor/github.com/fogleman/primitive/primitive/heatmap.go deleted file mode 100644 index 7bef5fe..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/heatmap.go +++ /dev/null @@ -1,59 +0,0 @@ -package primitive - -import ( - "image" - "image/color" - "math" -) - -type Heatmap struct { - W, H int - Count []uint64 -} - -func NewHeatmap(w, h int) *Heatmap { - count := make([]uint64, w*h) - return &Heatmap{w, h, count} -} - -func (h *Heatmap) Clear() { - for i := range h.Count { - h.Count[i] = 0 - } -} - -func (h *Heatmap) Add(lines []Scanline) { - for _, line := range lines { - i := line.Y*h.W + line.X1 - for x := line.X1; x <= line.X2; x++ { - h.Count[i] += uint64(line.Alpha) - i++ - } - } -} - -func (h *Heatmap) AddHeatmap(a *Heatmap) { - for i, x := range a.Count { - h.Count[i] += x - } -} - -func (h *Heatmap) Image(gamma float64) *image.Gray16 { - im := image.NewGray16(image.Rect(0, 0, h.W, h.H)) - var hi uint64 - for _, h := range h.Count { - if h > hi { - hi = h - } - } - i := 0 - for y := 0; y < h.H; y++ { - for x := 0; x < h.W; x++ { - p := float64(h.Count[i]) / float64(hi) - p = math.Pow(p, gamma) - im.SetGray16(x, y, color.Gray16{uint16(p * 0xffff)}) - i++ - } - } - return im -} diff --git a/vendor/github.com/fogleman/primitive/primitive/log.go b/vendor/github.com/fogleman/primitive/primitive/log.go deleted file mode 100644 index d162eff..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/log.go +++ /dev/null @@ -1,23 +0,0 @@ -package primitive - -import "fmt" - -var LogLevel int - -func Log(level int, format string, a ...interface{}) { - if LogLevel >= level { - fmt.Printf(format, a...) - } -} - -func v(format string, a ...interface{}) { - Log(1, format, a...) -} - -func vv(format string, a ...interface{}) { - Log(2, " "+format, a...) -} - -func vvv(format string, a ...interface{}) { - Log(3, " "+format, a...) -} diff --git a/vendor/github.com/fogleman/primitive/primitive/model.go b/vendor/github.com/fogleman/primitive/primitive/model.go deleted file mode 100644 index 80f49ae..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/model.go +++ /dev/null @@ -1,174 +0,0 @@ -package primitive - -import ( - "fmt" - "image" - "strings" - - "github.com/fogleman/gg" -) - -type Model struct { - Sw, Sh int - Scale float64 - Background Color - Target *image.RGBA - Current *image.RGBA - Context *gg.Context - Score float64 - Shapes []Shape - Colors []Color - Scores []float64 - Workers []*Worker -} - -func NewModel(target image.Image, background Color, size, numWorkers int) *Model { - w := target.Bounds().Size().X - h := target.Bounds().Size().Y - aspect := float64(w) / float64(h) - var sw, sh int - var scale float64 - if aspect >= 1 { - sw = size - sh = int(float64(size) / aspect) - scale = float64(size) / float64(w) - } else { - sw = int(float64(size) * aspect) - sh = size - scale = float64(size) / float64(h) - } - - model := &Model{} - model.Sw = sw - model.Sh = sh - model.Scale = scale - model.Background = background - model.Target = imageToRGBA(target) - model.Current = uniformRGBA(target.Bounds(), background.NRGBA()) - model.Score = differenceFull(model.Target, model.Current) - model.Context = model.newContext() - for i := 0; i < numWorkers; i++ { - worker := NewWorker(model.Target) - model.Workers = append(model.Workers, worker) - } - return model -} - -func (model *Model) newContext() *gg.Context { - dc := gg.NewContext(model.Sw, model.Sh) - dc.Scale(model.Scale, model.Scale) - dc.Translate(0.5, 0.5) - dc.SetColor(model.Background.NRGBA()) - dc.Clear() - return dc -} - -func (model *Model) Frames(scoreDelta float64) []image.Image { - var result []image.Image - dc := model.newContext() - result = append(result, imageToRGBA(dc.Image())) - previous := 10.0 - for i, shape := range model.Shapes { - c := model.Colors[i] - dc.SetRGBA255(c.R, c.G, c.B, c.A) - shape.Draw(dc, model.Scale) - dc.Fill() - score := model.Scores[i] - delta := previous - score - if delta >= scoreDelta { - previous = score - result = append(result, imageToRGBA(dc.Image())) - } - } - return result -} - -func (model *Model) SVG() string { - bg := model.Background - var lines []string - lines = append(lines, fmt.Sprintf("", model.Sw, model.Sh)) - lines = append(lines, fmt.Sprintf("", model.Sw, model.Sh, bg.R, bg.G, bg.B)) - lines = append(lines, fmt.Sprintf("", model.Scale)) - for i, shape := range model.Shapes { - c := model.Colors[i] - attrs := "fill=\"#%02x%02x%02x\" fill-opacity=\"%f\"" - attrs = fmt.Sprintf(attrs, c.R, c.G, c.B, float64(c.A)/255) - lines = append(lines, shape.SVG(attrs)) - } - lines = append(lines, "") - lines = append(lines, "") - return strings.Join(lines, "\n") -} - -func (model *Model) Add(shape Shape, alpha int) { - before := copyRGBA(model.Current) - lines := shape.Rasterize() - color := computeColor(model.Target, model.Current, lines, alpha) - drawLines(model.Current, color, lines) - score := differencePartial(model.Target, before, model.Current, model.Score, lines) - - model.Score = score - model.Shapes = append(model.Shapes, shape) - model.Colors = append(model.Colors, color) - model.Scores = append(model.Scores, score) - - model.Context.SetRGBA255(color.R, color.G, color.B, color.A) - shape.Draw(model.Context, model.Scale) -} - -func (model *Model) Step(shapeType ShapeType, alpha, repeat int) int { - state := model.runWorkers(shapeType, alpha, 1000, 100, 16) - // state = HillClimb(state, 1000).(*State) - model.Add(state.Shape, state.Alpha) - - for i := 0; i < repeat; i++ { - state.Worker.Init(model.Current, model.Score) - a := state.Energy() - state = HillClimb(state, 100).(*State) - b := state.Energy() - if a == b { - break - } - model.Add(state.Shape, state.Alpha) - } - - // for _, w := range model.Workers[1:] { - // model.Workers[0].Heatmap.AddHeatmap(w.Heatmap) - // } - // SavePNG("heatmap.png", model.Workers[0].Heatmap.Image(0.5)) - - counter := 0 - for _, worker := range model.Workers { - counter += worker.Counter - } - return counter -} - -func (model *Model) runWorkers(t ShapeType, a, n, age, m int) *State { - wn := len(model.Workers) - ch := make(chan *State, wn) - wm := m / wn - if m%wn != 0 { - wm++ - } - for i := 0; i < wn; i++ { - worker := model.Workers[i] - worker.Init(model.Current, model.Score) - go model.runWorker(worker, t, a, n, age, wm, ch) - } - var bestEnergy float64 - var bestState *State - for i := 0; i < wn; i++ { - state := <-ch - energy := state.Energy() - if i == 0 || energy < bestEnergy { - bestEnergy = energy - bestState = state - } - } - return bestState -} - -func (model *Model) runWorker(worker *Worker, t ShapeType, a, n, age, m int, ch chan *State) { - ch <- worker.BestHillClimbState(t, a, n, age, m) -} diff --git a/vendor/github.com/fogleman/primitive/primitive/optimize.go b/vendor/github.com/fogleman/primitive/primitive/optimize.go deleted file mode 100644 index e15d2b6..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/optimize.go +++ /dev/null @@ -1,75 +0,0 @@ -package primitive - -import ( - "math" - "math/rand" -) - -type Annealable interface { - Energy() float64 - DoMove() interface{} - UndoMove(interface{}) - Copy() Annealable -} - -func HillClimb(state Annealable, maxAge int) Annealable { - state = state.Copy() - bestState := state.Copy() - bestEnergy := state.Energy() - step := 0 - for age := 0; age < maxAge; age++ { - undo := state.DoMove() - energy := state.Energy() - if energy >= bestEnergy { - state.UndoMove(undo) - } else { - // fmt.Printf("step: %d, energy: %.6f\n", step, energy) - bestEnergy = energy - bestState = state.Copy() - age = -1 - } - step++ - } - return bestState -} - -func PreAnneal(state Annealable, iterations int) float64 { - state = state.Copy() - previous := state.Energy() - var total float64 - for i := 0; i < iterations; i++ { - state.DoMove() - energy := state.Energy() - total += math.Abs(energy - previous) - previous = energy - } - return total / float64(iterations) -} - -func Anneal(state Annealable, maxTemp, minTemp float64, steps int) Annealable { - factor := -math.Log(maxTemp / minTemp) - state = state.Copy() - bestState := state.Copy() - bestEnergy := state.Energy() - previousEnergy := bestEnergy - for step := 0; step < steps; step++ { - pct := float64(step) / float64(steps-1) - temp := maxTemp * math.Exp(factor*pct) - undo := state.DoMove() - energy := state.Energy() - change := energy - previousEnergy - if change > 0 && math.Exp(-change/temp) < rand.Float64() { - state.UndoMove(undo) - } else { - previousEnergy = energy - if energy < bestEnergy { - // pct := float64(step*100) / float64(steps) - // fmt.Printf("step: %d of %d (%.1f%%), temp: %.3f, energy: %.6f\n", - // step, steps, pct, temp, energy) - bestEnergy = energy - bestState = state.Copy() - } - } - } - return bestState -} diff --git a/vendor/github.com/fogleman/primitive/primitive/polygon.go b/vendor/github.com/fogleman/primitive/primitive/polygon.go deleted file mode 100644 index dee3a6c..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/polygon.go +++ /dev/null @@ -1,122 +0,0 @@ -package primitive - -import ( - "fmt" - "strings" - - "github.com/fogleman/gg" - "github.com/golang/freetype/raster" -) - -type Polygon struct { - Worker *Worker - Order int - Convex bool - X, Y []float64 -} - -func NewRandomPolygon(worker *Worker, order int, convex bool) *Polygon { - rnd := worker.Rnd - x := make([]float64, order) - y := make([]float64, order) - x[0] = rnd.Float64() * float64(worker.W) - y[0] = rnd.Float64() * float64(worker.H) - for i := 1; i < order; i++ { - x[i] = x[0] + rnd.Float64()*40 - 20 - y[i] = y[0] + rnd.Float64()*40 - 20 - } - p := &Polygon{worker, order, convex, x, y} - p.Mutate() - return p -} - -func (p *Polygon) Draw(dc *gg.Context, scale float64) { - dc.NewSubPath() - for i := 0; i < p.Order; i++ { - dc.LineTo(p.X[i], p.Y[i]) - } - dc.ClosePath() - dc.Fill() -} - -func (p *Polygon) SVG(attrs string) string { - ret := fmt.Sprintf( - "" -} - -func (p *Polygon) Copy() Shape { - a := *p - a.X = make([]float64, p.Order) - a.Y = make([]float64, p.Order) - copy(a.X, p.X) - copy(a.Y, p.Y) - return &a -} - -func (p *Polygon) Mutate() { - const m = 16 - w := p.Worker.W - h := p.Worker.H - rnd := p.Worker.Rnd - for { - if rnd.Float64() < 0.25 { - i := rnd.Intn(p.Order) - j := rnd.Intn(p.Order) - p.X[i], p.Y[i], p.X[j], p.Y[j] = p.X[j], p.Y[j], p.X[i], p.Y[i] - } else { - i := rnd.Intn(p.Order) - p.X[i] = clamp(p.X[i]+rnd.NormFloat64()*16, -m, float64(w-1+m)) - p.Y[i] = clamp(p.Y[i]+rnd.NormFloat64()*16, -m, float64(h-1+m)) - } - if p.Valid() { - break - } - } -} - -func (p *Polygon) Valid() bool { - if !p.Convex { - return true - } - var sign bool - for a := 0; a < p.Order; a++ { - i := (a + 0) % p.Order - j := (a + 1) % p.Order - k := (a + 2) % p.Order - c := cross3(p.X[i], p.Y[i], p.X[j], p.Y[j], p.X[k], p.Y[k]) - if a == 0 { - sign = c > 0 - } else if c > 0 != sign { - return false - } - } - return true -} - -func cross3(x1, y1, x2, y2, x3, y3 float64) float64 { - dx1 := x2 - x1 - dy1 := y2 - y1 - dx2 := x3 - x2 - dy2 := y3 - y2 - return dx1*dy2 - dy1*dx2 -} - -func (p *Polygon) Rasterize() []Scanline { - var path raster.Path - for i := 0; i <= p.Order; i++ { - f := fixp(p.X[i%p.Order], p.Y[i%p.Order]) - if i == 0 { - path.Start(f) - } else { - path.Add1(f) - } - } - return fillPath(p.Worker, path) -} diff --git a/vendor/github.com/fogleman/primitive/primitive/quadratic.go b/vendor/github.com/fogleman/primitive/primitive/quadratic.go deleted file mode 100644 index 740d44a..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/quadratic.go +++ /dev/null @@ -1,100 +0,0 @@ -package primitive - -import ( - "fmt" - "strings" - - "github.com/fogleman/gg" - "github.com/golang/freetype/raster" -) - -type Quadratic struct { - Worker *Worker - X1, Y1 float64 - X2, Y2 float64 - X3, Y3 float64 - Width float64 -} - -func NewRandomQuadratic(worker *Worker) *Quadratic { - rnd := worker.Rnd - x1 := rnd.Float64() * float64(worker.W) - y1 := rnd.Float64() * float64(worker.H) - x2 := x1 + rnd.Float64()*40 - 20 - y2 := y1 + rnd.Float64()*40 - 20 - x3 := x2 + rnd.Float64()*40 - 20 - y3 := y2 + rnd.Float64()*40 - 20 - width := 1.0 / 2 - q := &Quadratic{worker, x1, y1, x2, y2, x3, y3, width} - q.Mutate() - return q -} - -func (q *Quadratic) Draw(dc *gg.Context, scale float64) { - dc.MoveTo(q.X1, q.Y1) - dc.QuadraticTo(q.X2, q.Y2, q.X3, q.Y3) - dc.SetLineWidth(q.Width * scale) - dc.Stroke() -} - -func (q *Quadratic) SVG(attrs string) string { - // TODO: this is a little silly - attrs = strings.Replace(attrs, "fill", "stroke", -1) - return fmt.Sprintf( - "", - attrs, q.X1, q.Y1, q.X2, q.Y2, q.X3, q.Y3, q.Width) -} - -func (q *Quadratic) Copy() Shape { - a := *q - return &a -} - -func (q *Quadratic) Mutate() { - const m = 16 - w := q.Worker.W - h := q.Worker.H - rnd := q.Worker.Rnd - for { - switch rnd.Intn(3) { - case 0: - q.X1 = clamp(q.X1+rnd.NormFloat64()*16, -m, float64(w-1+m)) - q.Y1 = clamp(q.Y1+rnd.NormFloat64()*16, -m, float64(h-1+m)) - case 1: - q.X2 = clamp(q.X2+rnd.NormFloat64()*16, -m, float64(w-1+m)) - q.Y2 = clamp(q.Y2+rnd.NormFloat64()*16, -m, float64(h-1+m)) - case 2: - q.X3 = clamp(q.X3+rnd.NormFloat64()*16, -m, float64(w-1+m)) - q.Y3 = clamp(q.Y3+rnd.NormFloat64()*16, -m, float64(h-1+m)) - case 3: - q.Width = clamp(q.Width+rnd.NormFloat64(), 1, 16) - } - if q.Valid() { - break - } - } -} - -func (q *Quadratic) Valid() bool { - dx12 := int(q.X1 - q.X2) - dy12 := int(q.Y1 - q.Y2) - dx23 := int(q.X2 - q.X3) - dy23 := int(q.Y2 - q.Y3) - dx13 := int(q.X1 - q.X3) - dy13 := int(q.Y1 - q.Y3) - d12 := dx12*dx12 + dy12*dy12 - d23 := dx23*dx23 + dy23*dy23 - d13 := dx13*dx13 + dy13*dy13 - return d13 > d12 && d13 > d23 -} - -func (q *Quadratic) Rasterize() []Scanline { - var path raster.Path - p1 := fixp(q.X1, q.Y1) - p2 := fixp(q.X2, q.Y2) - p3 := fixp(q.X3, q.Y3) - path.Start(p1) - path.Add2(p2, p3) - width := fix(q.Width) - return strokePath(q.Worker, path, width, raster.RoundCapper, raster.RoundJoiner) -} diff --git a/vendor/github.com/fogleman/primitive/primitive/raster.go b/vendor/github.com/fogleman/primitive/primitive/raster.go deleted file mode 100644 index a5d620a..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/raster.go +++ /dev/null @@ -1,46 +0,0 @@ -package primitive - -import ( - "github.com/golang/freetype/raster" - "golang.org/x/image/math/fixed" -) - -func fix(x float64) fixed.Int26_6 { - return fixed.Int26_6(x * 64) -} - -func fixp(x, y float64) fixed.Point26_6 { - return fixed.Point26_6{fix(x), fix(y)} -} - -type painter struct { - Lines []Scanline -} - -func (p *painter) Paint(spans []raster.Span, done bool) { - for _, span := range spans { - p.Lines = append(p.Lines, Scanline{span.Y, span.X0, span.X1 - 1, span.Alpha}) - } -} - -func fillPath(worker *Worker, path raster.Path) []Scanline { - r := worker.Rasterizer - r.Clear() - r.UseNonZeroWinding = true - r.AddPath(path) - var p painter - p.Lines = worker.Lines[:0] - r.Rasterize(&p) - return p.Lines -} - -func strokePath(worker *Worker, path raster.Path, width fixed.Int26_6, cr raster.Capper, jr raster.Joiner) []Scanline { - r := worker.Rasterizer - r.Clear() - r.UseNonZeroWinding = true - r.AddStroke(path, width, cr, jr) - var p painter - p.Lines = worker.Lines[:0] - r.Rasterize(&p) - return p.Lines -} diff --git a/vendor/github.com/fogleman/primitive/primitive/rectangle.go b/vendor/github.com/fogleman/primitive/primitive/rectangle.go deleted file mode 100644 index a2813c9..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/rectangle.go +++ /dev/null @@ -1,198 +0,0 @@ -package primitive - -import ( - "fmt" - "math" - - "github.com/fogleman/gg" -) - -type Rectangle struct { - Worker *Worker - X1, Y1 int - X2, Y2 int -} - -func NewRandomRectangle(worker *Worker) *Rectangle { - rnd := worker.Rnd - x1 := rnd.Intn(worker.W) - y1 := rnd.Intn(worker.H) - x2 := clampInt(x1+rnd.Intn(32)+1, 0, worker.W-1) - y2 := clampInt(y1+rnd.Intn(32)+1, 0, worker.H-1) - return &Rectangle{worker, x1, y1, x2, y2} -} - -func (r *Rectangle) bounds() (x1, y1, x2, y2 int) { - x1, y1 = r.X1, r.Y1 - x2, y2 = r.X2, r.Y2 - if x1 > x2 { - x1, x2 = x2, x1 - } - if y1 > y2 { - y1, y2 = y2, y1 - } - return -} - -func (r *Rectangle) Draw(dc *gg.Context, scale float64) { - x1, y1, x2, y2 := r.bounds() - dc.DrawRectangle(float64(x1), float64(y1), float64(x2-x1+1), float64(y2-y1+1)) - dc.Fill() -} - -func (r *Rectangle) SVG(attrs string) string { - x1, y1, x2, y2 := r.bounds() - w := x2 - x1 + 1 - h := y2 - y1 + 1 - return fmt.Sprintf( - "", - attrs, x1, y1, w, h) -} - -func (r *Rectangle) Copy() Shape { - a := *r - return &a -} - -func (r *Rectangle) Mutate() { - w := r.Worker.W - h := r.Worker.H - rnd := r.Worker.Rnd - switch rnd.Intn(2) { - case 0: - r.X1 = clampInt(r.X1+int(rnd.NormFloat64()*16), 0, w-1) - r.Y1 = clampInt(r.Y1+int(rnd.NormFloat64()*16), 0, h-1) - case 1: - r.X2 = clampInt(r.X2+int(rnd.NormFloat64()*16), 0, w-1) - r.Y2 = clampInt(r.Y2+int(rnd.NormFloat64()*16), 0, h-1) - } -} - -func (r *Rectangle) Rasterize() []Scanline { - x1, y1, x2, y2 := r.bounds() - lines := r.Worker.Lines[:0] - for y := y1; y <= y2; y++ { - lines = append(lines, Scanline{y, x1, x2, 0xffff}) - } - return lines -} - -type RotatedRectangle struct { - Worker *Worker - X, Y int - Sx, Sy int - Angle int -} - -func NewRandomRotatedRectangle(worker *Worker) *RotatedRectangle { - rnd := worker.Rnd - x := rnd.Intn(worker.W) - y := rnd.Intn(worker.H) - sx := rnd.Intn(32) + 1 - sy := rnd.Intn(32) + 1 - a := rnd.Intn(360) - r := &RotatedRectangle{worker, x, y, sx, sy, a} - r.Mutate() - return r -} - -func (r *RotatedRectangle) Draw(dc *gg.Context, scale float64) { - sx, sy := float64(r.Sx), float64(r.Sy) - dc.Push() - dc.Translate(float64(r.X), float64(r.Y)) - dc.Rotate(radians(float64(r.Angle))) - dc.DrawRectangle(-sx/2, -sy/2, sx, sy) - dc.Pop() - dc.Fill() -} - -func (r *RotatedRectangle) SVG(attrs string) string { - return fmt.Sprintf( - "", - r.X, r.Y, r.Angle, r.Sx, r.Sy, attrs) -} - -func (r *RotatedRectangle) Copy() Shape { - a := *r - return &a -} - -func (r *RotatedRectangle) Mutate() { - w := r.Worker.W - h := r.Worker.H - rnd := r.Worker.Rnd - switch rnd.Intn(3) { - case 0: - r.X = clampInt(r.X+int(rnd.NormFloat64()*16), 0, w-1) - r.Y = clampInt(r.Y+int(rnd.NormFloat64()*16), 0, h-1) - case 1: - r.Sx = clampInt(r.Sx+int(rnd.NormFloat64()*16), 1, w-1) - r.Sy = clampInt(r.Sy+int(rnd.NormFloat64()*16), 1, h-1) - case 2: - r.Angle = r.Angle + int(rnd.NormFloat64()*32) - } - // for !r.Valid() { - // r.Sx = clampInt(r.Sx+int(rnd.NormFloat64()*16), 0, w-1) - // r.Sy = clampInt(r.Sy+int(rnd.NormFloat64()*16), 0, h-1) - // } -} - -func (r *RotatedRectangle) Valid() bool { - a, b := r.Sx, r.Sy - if a < b { - a, b = b, a - } - aspect := float64(a) / float64(b) - return aspect <= 5 -} - -func (r *RotatedRectangle) Rasterize() []Scanline { - w := r.Worker.W - h := r.Worker.H - sx, sy := float64(r.Sx), float64(r.Sy) - angle := radians(float64(r.Angle)) - rx1, ry1 := rotate(-sx/2, -sy/2, angle) - rx2, ry2 := rotate(sx/2, -sy/2, angle) - rx3, ry3 := rotate(sx/2, sy/2, angle) - rx4, ry4 := rotate(-sx/2, sy/2, angle) - x1, y1 := int(rx1)+r.X, int(ry1)+r.Y - x2, y2 := int(rx2)+r.X, int(ry2)+r.Y - x3, y3 := int(rx3)+r.X, int(ry3)+r.Y - x4, y4 := int(rx4)+r.X, int(ry4)+r.Y - miny := minInt(y1, minInt(y2, minInt(y3, y4))) - maxy := maxInt(y1, maxInt(y2, maxInt(y3, y4))) - n := maxy - miny + 1 - min := make([]int, n) - max := make([]int, n) - for i := range min { - min[i] = w - } - xs := []int{x1, x2, x3, x4, x1} - ys := []int{y1, y2, y3, y4, y1} - // TODO: this could be better probably - for i := 0; i < 4; i++ { - x, y := float64(xs[i]), float64(ys[i]) - dx, dy := float64(xs[i+1]-xs[i]), float64(ys[i+1]-ys[i]) - count := int(math.Sqrt(dx*dx+dy*dy)) * 2 - for j := 0; j < count; j++ { - t := float64(j) / float64(count-1) - xi := int(x + dx*t) - yi := int(y+dy*t) - miny - min[yi] = minInt(min[yi], xi) - max[yi] = maxInt(max[yi], xi) - } - } - lines := r.Worker.Lines[:0] - for i := 0; i < n; i++ { - y := miny + i - if y < 0 || y >= h { - continue - } - a := maxInt(min[i], 0) - b := minInt(max[i], w-1) - if b >= a { - lines = append(lines, Scanline{y, a, b, 0xffff}) - } - } - return lines -} diff --git a/vendor/github.com/fogleman/primitive/primitive/scanline.go b/vendor/github.com/fogleman/primitive/primitive/scanline.go deleted file mode 100644 index 852f6a2..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/scanline.go +++ /dev/null @@ -1,29 +0,0 @@ -package primitive - -type Scanline struct { - Y, X1, X2 int - Alpha uint32 -} - -func cropScanlines(lines []Scanline, w, h int) []Scanline { - i := 0 - for _, line := range lines { - if line.Y < 0 || line.Y >= h { - continue - } - if line.X1 >= w { - continue - } - if line.X2 < 0 { - continue - } - line.X1 = clampInt(line.X1, 0, w-1) - line.X2 = clampInt(line.X2, 0, w-1) - if line.X1 > line.X2 { - continue - } - lines[i] = line - i++ - } - return lines[:i] -} diff --git a/vendor/github.com/fogleman/primitive/primitive/shape.go b/vendor/github.com/fogleman/primitive/primitive/shape.go deleted file mode 100644 index cb0fbe4..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/shape.go +++ /dev/null @@ -1,25 +0,0 @@ -package primitive - -import "github.com/fogleman/gg" - -type Shape interface { - Rasterize() []Scanline - Copy() Shape - Mutate() - Draw(dc *gg.Context, scale float64) - SVG(attrs string) string -} - -type ShapeType int - -const ( - ShapeTypeAny ShapeType = iota - ShapeTypeTriangle - ShapeTypeRectangle - ShapeTypeEllipse - ShapeTypeCircle - ShapeTypeRotatedRectangle - ShapeTypeQuadratic - ShapeTypeRotatedEllipse - ShapeTypePolygon -) diff --git a/vendor/github.com/fogleman/primitive/primitive/state.go b/vendor/github.com/fogleman/primitive/primitive/state.go deleted file mode 100644 index 33dda2b..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/state.go +++ /dev/null @@ -1,48 +0,0 @@ -package primitive - -type State struct { - Worker *Worker - Shape Shape - Alpha int - MutateAlpha bool - Score float64 -} - -func NewState(worker *Worker, shape Shape, alpha int) *State { - var mutateAlpha bool - if alpha == 0 { - alpha = 128 - mutateAlpha = true - } - return &State{worker, shape, alpha, mutateAlpha, -1} -} - -func (state *State) Energy() float64 { - if state.Score < 0 { - state.Score = state.Worker.Energy(state.Shape, state.Alpha) - } - return state.Score -} - -func (state *State) DoMove() interface{} { - rnd := state.Worker.Rnd - oldState := state.Copy() - state.Shape.Mutate() - if state.MutateAlpha { - state.Alpha = clampInt(state.Alpha+rnd.Intn(21)-10, 1, 255) - } - state.Score = -1 - return oldState -} - -func (state *State) UndoMove(undo interface{}) { - oldState := undo.(*State) - state.Shape = oldState.Shape - state.Alpha = oldState.Alpha - state.Score = oldState.Score -} - -func (state *State) Copy() Annealable { - return &State{ - state.Worker, state.Shape.Copy(), state.Alpha, state.MutateAlpha, state.Score} -} diff --git a/vendor/github.com/fogleman/primitive/primitive/triangle.go b/vendor/github.com/fogleman/primitive/primitive/triangle.go deleted file mode 100644 index c55da21..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/triangle.go +++ /dev/null @@ -1,171 +0,0 @@ -package primitive - -import ( - "fmt" - "math" - - "github.com/fogleman/gg" -) - -type Triangle struct { - Worker *Worker - X1, Y1 int - X2, Y2 int - X3, Y3 int -} - -func NewRandomTriangle(worker *Worker) *Triangle { - rnd := worker.Rnd - x1 := rnd.Intn(worker.W) - y1 := rnd.Intn(worker.H) - x2 := x1 + rnd.Intn(31) - 15 - y2 := y1 + rnd.Intn(31) - 15 - x3 := x1 + rnd.Intn(31) - 15 - y3 := y1 + rnd.Intn(31) - 15 - t := &Triangle{worker, x1, y1, x2, y2, x3, y3} - t.Mutate() - return t -} - -func (t *Triangle) Draw(dc *gg.Context, scale float64) { - dc.LineTo(float64(t.X1), float64(t.Y1)) - dc.LineTo(float64(t.X2), float64(t.Y2)) - dc.LineTo(float64(t.X3), float64(t.Y3)) - dc.ClosePath() - dc.Fill() -} - -func (t *Triangle) SVG(attrs string) string { - return fmt.Sprintf( - "", - attrs, t.X1, t.Y1, t.X2, t.Y2, t.X3, t.Y3) -} - -func (t *Triangle) Copy() Shape { - a := *t - return &a -} - -func (t *Triangle) Mutate() { - w := t.Worker.W - h := t.Worker.H - rnd := t.Worker.Rnd - const m = 16 - for { - switch rnd.Intn(3) { - case 0: - t.X1 = clampInt(t.X1+int(rnd.NormFloat64()*16), -m, w-1+m) - t.Y1 = clampInt(t.Y1+int(rnd.NormFloat64()*16), -m, h-1+m) - case 1: - t.X2 = clampInt(t.X2+int(rnd.NormFloat64()*16), -m, w-1+m) - t.Y2 = clampInt(t.Y2+int(rnd.NormFloat64()*16), -m, h-1+m) - case 2: - t.X3 = clampInt(t.X3+int(rnd.NormFloat64()*16), -m, w-1+m) - t.Y3 = clampInt(t.Y3+int(rnd.NormFloat64()*16), -m, h-1+m) - } - if t.Valid() { - break - } - } -} - -func (t *Triangle) Valid() bool { - const minDegrees = 15 - var a1, a2, a3 float64 - { - x1 := float64(t.X2 - t.X1) - y1 := float64(t.Y2 - t.Y1) - x2 := float64(t.X3 - t.X1) - y2 := float64(t.Y3 - t.Y1) - d1 := math.Sqrt(x1*x1 + y1*y1) - d2 := math.Sqrt(x2*x2 + y2*y2) - x1 /= d1 - y1 /= d1 - x2 /= d2 - y2 /= d2 - a1 = degrees(math.Acos(x1*x2 + y1*y2)) - } - { - x1 := float64(t.X1 - t.X2) - y1 := float64(t.Y1 - t.Y2) - x2 := float64(t.X3 - t.X2) - y2 := float64(t.Y3 - t.Y2) - d1 := math.Sqrt(x1*x1 + y1*y1) - d2 := math.Sqrt(x2*x2 + y2*y2) - x1 /= d1 - y1 /= d1 - x2 /= d2 - y2 /= d2 - a2 = degrees(math.Acos(x1*x2 + y1*y2)) - } - a3 = 180 - a1 - a2 - return a1 > minDegrees && a2 > minDegrees && a3 > minDegrees -} - -func (t *Triangle) Rasterize() []Scanline { - buf := t.Worker.Lines[:0] - lines := rasterizeTriangle(t.X1, t.Y1, t.X2, t.Y2, t.X3, t.Y3, buf) - return cropScanlines(lines, t.Worker.W, t.Worker.H) -} - -func rasterizeTriangle(x1, y1, x2, y2, x3, y3 int, buf []Scanline) []Scanline { - if y1 > y3 { - x1, x3 = x3, x1 - y1, y3 = y3, y1 - } - if y1 > y2 { - x1, x2 = x2, x1 - y1, y2 = y2, y1 - } - if y2 > y3 { - x2, x3 = x3, x2 - y2, y3 = y3, y2 - } - if y2 == y3 { - return rasterizeTriangleBottom(x1, y1, x2, y2, x3, y3, buf) - } else if y1 == y2 { - return rasterizeTriangleTop(x1, y1, x2, y2, x3, y3, buf) - } else { - x4 := x1 + int((float64(y2-y1)/float64(y3-y1))*float64(x3-x1)) - y4 := y2 - buf = rasterizeTriangleBottom(x1, y1, x2, y2, x4, y4, buf) - buf = rasterizeTriangleTop(x2, y2, x4, y4, x3, y3, buf) - return buf - } -} - -func rasterizeTriangleBottom(x1, y1, x2, y2, x3, y3 int, buf []Scanline) []Scanline { - s1 := float64(x2-x1) / float64(y2-y1) - s2 := float64(x3-x1) / float64(y3-y1) - ax := float64(x1) - bx := float64(x1) - for y := y1; y <= y2; y++ { - a := int(ax) - b := int(bx) - ax += s1 - bx += s2 - if a > b { - a, b = b, a - } - buf = append(buf, Scanline{y, a, b, 0xffff}) - } - return buf -} - -func rasterizeTriangleTop(x1, y1, x2, y2, x3, y3 int, buf []Scanline) []Scanline { - s1 := float64(x3-x1) / float64(y3-y1) - s2 := float64(x3-x2) / float64(y3-y2) - ax := float64(x3) - bx := float64(x3) - for y := y3; y > y1; y-- { - ax -= s1 - bx -= s2 - a := int(ax) - b := int(bx) - if a > b { - a, b = b, a - } - buf = append(buf, Scanline{y, a, b, 0xffff}) - } - return buf -} diff --git a/vendor/github.com/fogleman/primitive/primitive/util.go b/vendor/github.com/fogleman/primitive/primitive/util.go deleted file mode 100644 index 4a4a46d..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/util.go +++ /dev/null @@ -1,195 +0,0 @@ -package primitive - -import ( - "fmt" - "image" - "image/color" - "image/color/palette" - "image/draw" - "image/gif" - "image/jpeg" - "image/png" - "io/ioutil" - "math" - "os" - "os/exec" - "path/filepath" -) - -func LoadImage(path string) (image.Image, error) { - file, err := os.Open(path) - if err != nil { - return nil, err - } - defer file.Close() - im, _, err := image.Decode(file) - return im, err -} - -func SaveFile(path, contents string) error { - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - _, err = file.WriteString(contents) - return err -} - -func SavePNG(path string, im image.Image) error { - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - return png.Encode(file, im) -} - -func SaveJPG(path string, im image.Image, quality int) error { - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - return jpeg.Encode(file, im, &jpeg.Options{quality}) -} - -func SaveGIF(path string, frames []image.Image, delay, lastDelay int) error { - g := gif.GIF{} - for i, src := range frames { - dst := image.NewPaletted(src.Bounds(), palette.Plan9) - draw.Draw(dst, dst.Rect, src, image.ZP, draw.Src) - g.Image = append(g.Image, dst) - if i == len(frames)-1 { - g.Delay = append(g.Delay, lastDelay) - } else { - g.Delay = append(g.Delay, delay) - } - } - file, err := os.Create(path) - if err != nil { - return err - } - defer file.Close() - return gif.EncodeAll(file, &g) -} - -func SaveGIFImageMagick(path string, frames []image.Image, delay, lastDelay int) error { - dir, err := ioutil.TempDir("", "") - if err != nil { - return err - } - for i, im := range frames { - path := filepath.Join(dir, fmt.Sprintf("%06d.png", i)) - SavePNG(path, im) - } - args := []string{ - "-loop", "0", - "-delay", fmt.Sprint(delay), - filepath.Join(dir, "*.png"), - "-delay", fmt.Sprint(lastDelay - delay), - filepath.Join(dir, fmt.Sprintf("%06d.png", len(frames)-1)), - path, - } - cmd := exec.Command("convert", args...) - if err := cmd.Run(); err != nil { - return err - } - return os.RemoveAll(dir) -} - -func NumberString(x float64) string { - suffixes := []string{"", "k", "M", "G"} - for _, suffix := range suffixes { - if x < 1000 { - return fmt.Sprintf("%.1f%s", x, suffix) - } - x /= 1000 - } - return fmt.Sprintf("%.1f%s", x, "T") -} - -func radians(degrees float64) float64 { - return degrees * math.Pi / 180 -} - -func degrees(radians float64) float64 { - return radians * 180 / math.Pi -} - -func clamp(x, lo, hi float64) float64 { - if x < lo { - return lo - } - if x > hi { - return hi - } - return x -} - -func clampInt(x, lo, hi int) int { - if x < lo { - return lo - } - if x > hi { - return hi - } - return x -} - -func minInt(a, b int) int { - if a < b { - return a - } - return b -} - -func maxInt(a, b int) int { - if a > b { - return a - } - return b -} - -func rotate(x, y, theta float64) (rx, ry float64) { - rx = x*math.Cos(theta) - y*math.Sin(theta) - ry = x*math.Sin(theta) + y*math.Cos(theta) - return -} - -func imageToRGBA(src image.Image) *image.RGBA { - dst := image.NewRGBA(src.Bounds()) - draw.Draw(dst, dst.Rect, src, image.ZP, draw.Src) - return dst -} - -func copyRGBA(src *image.RGBA) *image.RGBA { - dst := image.NewRGBA(src.Bounds()) - copy(dst.Pix, src.Pix) - return dst -} - -func uniformRGBA(r image.Rectangle, c color.Color) *image.RGBA { - im := image.NewRGBA(r) - draw.Draw(im, im.Bounds(), &image.Uniform{c}, image.ZP, draw.Src) - return im -} - -func AverageImageColor(im image.Image) color.NRGBA { - rgba := imageToRGBA(im) - size := rgba.Bounds().Size() - w, h := size.X, size.Y - var r, g, b int - for y := 0; y < h; y++ { - for x := 0; x < w; x++ { - c := rgba.RGBAAt(x, y) - r += int(c.R) - g += int(c.G) - b += int(c.B) - } - } - r /= w * h - g /= w * h - b /= w * h - return color.NRGBA{uint8(r), uint8(g), uint8(b), 255} -} diff --git a/vendor/github.com/fogleman/primitive/primitive/worker.go b/vendor/github.com/fogleman/primitive/primitive/worker.go deleted file mode 100644 index d99eed5..0000000 --- a/vendor/github.com/fogleman/primitive/primitive/worker.go +++ /dev/null @@ -1,108 +0,0 @@ -package primitive - -import ( - "image" - "math/rand" - "time" - - "github.com/golang/freetype/raster" -) - -type Worker struct { - W, H int - Target *image.RGBA - Current *image.RGBA - Buffer *image.RGBA - Rasterizer *raster.Rasterizer - Lines []Scanline - Heatmap *Heatmap - Rnd *rand.Rand - Score float64 - Counter int -} - -func NewWorker(target *image.RGBA) *Worker { - w := target.Bounds().Size().X - h := target.Bounds().Size().Y - worker := Worker{} - worker.W = w - worker.H = h - worker.Target = target - worker.Buffer = image.NewRGBA(target.Bounds()) - worker.Rasterizer = raster.NewRasterizer(w, h) - worker.Lines = make([]Scanline, 0, 4096) // TODO: based on height - worker.Heatmap = NewHeatmap(w, h) - worker.Rnd = rand.New(rand.NewSource(time.Now().UnixNano())) - return &worker -} - -func (worker *Worker) Init(current *image.RGBA, score float64) { - worker.Current = current - worker.Score = score - worker.Counter = 0 - worker.Heatmap.Clear() -} - -func (worker *Worker) Energy(shape Shape, alpha int) float64 { - worker.Counter++ - lines := shape.Rasterize() - // worker.Heatmap.Add(lines) - color := computeColor(worker.Target, worker.Current, lines, alpha) - copyLines(worker.Buffer, worker.Current, lines) - drawLines(worker.Buffer, color, lines) - return differencePartial(worker.Target, worker.Current, worker.Buffer, worker.Score, lines) -} - -func (worker *Worker) BestHillClimbState(t ShapeType, a, n, age, m int) *State { - var bestEnergy float64 - var bestState *State - for i := 0; i < m; i++ { - state := worker.BestRandomState(t, a, n) - before := state.Energy() - state = HillClimb(state, age).(*State) - energy := state.Energy() - vv("%dx random: %.6f -> %dx hill climb: %.6f\n", n, before, age, energy) - if i == 0 || energy < bestEnergy { - bestEnergy = energy - bestState = state - } - } - return bestState -} - -func (worker *Worker) BestRandomState(t ShapeType, a, n int) *State { - var bestEnergy float64 - var bestState *State - for i := 0; i < n; i++ { - state := worker.RandomState(t, a) - energy := state.Energy() - if i == 0 || energy < bestEnergy { - bestEnergy = energy - bestState = state - } - } - return bestState -} - -func (worker *Worker) RandomState(t ShapeType, a int) *State { - switch t { - default: - return worker.RandomState(ShapeType(worker.Rnd.Intn(8)+1), a) - case ShapeTypeTriangle: - return NewState(worker, NewRandomTriangle(worker), a) - case ShapeTypeRectangle: - return NewState(worker, NewRandomRectangle(worker), a) - case ShapeTypeEllipse: - return NewState(worker, NewRandomEllipse(worker), a) - case ShapeTypeCircle: - return NewState(worker, NewRandomCircle(worker), a) - case ShapeTypeRotatedRectangle: - return NewState(worker, NewRandomRotatedRectangle(worker), a) - case ShapeTypeQuadratic: - return NewState(worker, NewRandomQuadratic(worker), a) - case ShapeTypeRotatedEllipse: - return NewState(worker, NewRandomRotatedEllipse(worker), a) - case ShapeTypePolygon: - return NewState(worker, NewRandomPolygon(worker, 4, false), a) - } -} -- cgit v1.2.3