package util import ( "fmt" "strconv" svg "github.com/ajstarks/svgo/float" ) type PointMap map[int]Point func (pm PointMap) Scale(s float64) PointMap { pointMap := make(PointMap, len(pm)) for i, p := range pm { pointMap[i] = p.Multiply(s) } return pointMap } func (pm PointMap) Box() (Point, Point) { min := Point{} max := Point{} for _, p := range pm { min = min.Min(p) max = max.Max(p) } return min, max } func (pm PointMap) Offset(point Point) PointMap { pointMap := make(PointMap, len(pm)) for i, p := range pm { pointMap[i] = p.Subtract(point) } return pointMap } func (pm PointMap) Normalize() PointMap { min, _ := pm.Box() return pm.Offset(min) } func (pm PointMap) Draw(canvas *svg.SVG) { for i, point := range pm.Normalize() { canvas.Circle(point.X, point.Y, 2.0, "stroke:black;fill:black") canvas.Text(point.X+2, point.Y+2, strconv.Itoa(i)) } } func (pm PointMap) Line(canvas *svg.SVG, lines ...int) { for i := 0; i < len(lines)-1; i++ { start := lines[i] end := lines[i+1] canvas.Line(pm[start].X, pm[start].Y, pm[end].X, pm[end].Y, "stroke:black;stroke-width:3") } } func (pm PointMap) Bezier(canvas *svg.SVG, lines ...int) error { if len(lines) != 4 { return fmt.Errorf("expected 4 line definitons, got %d instead", len(lines)) } canvas.Bezier(pm[lines[0]].X, pm[lines[0]].Y, pm[lines[1]].X, pm[lines[1]].Y, pm[lines[2]].X, pm[lines[2]].Y, pm[lines[3]].X, pm[lines[3]].Y, "stroke:black;fill:none") return nil }