diff --git a/cmd/tileblueprint/tileblueprint.go b/cmd/tileblueprint/tileblueprint.go index 73e9690..35957fc 100644 --- a/cmd/tileblueprint/tileblueprint.go +++ b/cmd/tileblueprint/tileblueprint.go @@ -19,45 +19,102 @@ func main() { } } +type projection interface { + tile() (width float64, height float64) + draw(gc *draw2dimg.GraphicContext, x, y, w, h, scale float64, p palette) +} + +type cabinet struct { +} + +func (cabinet) tile() (float64, float64) { + return 150, 140 +} + +func (cabinet) draw(gc *draw2dimg.GraphicContext, x, y, w, h, scale float64, p palette) { + dw := func(d float64) float64 { return (d / w) * w * scale } + dh := func(d float64) float64 { return (d / h) * h * scale } + gc.MoveTo(x, y+dh(40)) + gc.LineTo(x, y+h) + gc.LineTo(x+dw(100), y+h) + gc.LineTo(x+w, y+dh(100)) + gc.LineTo(x+w, y) + gc.LineTo(x+dw(100), y+dh(40)) + gc.LineTo(x+dw(100), y+h) + gc.MoveTo(x+dw(100), y+dh(40)) + gc.LineTo(x, y+dh(40)) + gc.LineTo(x+dw(50), y) + gc.LineTo(x+w, y) + gc.LineTo(x+dw(100), y+dh(40)) + gc.SetStrokeColor(p.tile) + gc.Stroke() +} + +type isometric struct { +} + +func (isometric) tile() (float64, float64) { + return 140, 200 +} + +type palette struct { + margin color.Color + tile color.Color +} + +func (isometric) draw(gc *draw2dimg.GraphicContext, x, y, w, h, scale float64, p palette) { + gc.MoveTo(x, y+.25*h) + gc.LineTo(x, y+.75*h) + gc.LineTo(x+.5*w, y+h) + gc.LineTo(x+w, y+.75*h) + gc.LineTo(x+w, y+.25*h) + gc.LineTo(x+.5*w, y+.5*h) + gc.LineTo(x, y+.25*h) + gc.LineTo(x+.5*w, y) + gc.LineTo(x+w, y+.25*h) + gc.MoveTo(x+.5*w, y+.5*h) + gc.LineTo(x+.5*w, y+h) + gc.SetStrokeColor(p.tile) + gc.Stroke() +} + func run() error { var dpi int + var proj string flag.IntVar(&dpi, "dpi", 300, "dpi") + flag.StringVar(&proj, "projection", "", "projection: either isometric (default) or cabinet") flag.Parse() path := flag.Arg(0) if path == "" { return errors.New("no output path specified") } + var p projection + switch proj { + case "cabinet": + p = cabinet{} + default: + p = isometric{} + } + bounds := image.Rect(0, 0, dpi*827/100, dpi*1169/100) scale := float64(dpi) / 100 margin := 5. * scale - tileWidth, tileHeight := 140.*scale, 200.*scale + tileWidth, tileHeight := p.tile() + tileWidth, tileHeight = tileWidth*scale, tileHeight*scale tileOffsetWidth, tileOffsetHeight := tileWidth+4.*margin, tileHeight+4.*margin im := image.NewRGBA(bounds) gc := draw2dimg.NewGraphicContext(im) - marginColor := color.Gray{Y: 63} - tileColor := color.Gray{Y: 127} gc.SetLineWidth(1) + palette := palette{margin: color.Gray{Y: 63}, tile: color.Gray{Y: 127}} for y := 0.; y < float64(bounds.Max.Y)-tileOffsetHeight; y += tileOffsetHeight { for x := 0.; x < float64(bounds.Max.X)-tileOffsetWidth; x += tileOffsetWidth { draw2dkit.Rectangle(gc, x+margin-1, y+margin-1, x+tileOffsetWidth-margin, y+tileOffsetHeight-margin) - gc.SetStrokeColor(marginColor) + gc.SetStrokeColor(palette.margin) gc.Stroke() tileX, tileY := x+2*margin-.5, y+2*margin-.5 - gc.MoveTo(tileX, tileY+.25*tileHeight) - gc.LineTo(tileX, tileY+.75*tileHeight) - gc.LineTo(tileX+.5*tileWidth, tileY+tileHeight) - gc.LineTo(tileX+tileWidth, tileY+.75*tileHeight) - gc.LineTo(tileX+tileWidth, tileY+.25*tileHeight) - gc.LineTo(tileX+.5*tileWidth, tileY+.5*tileHeight) - gc.LineTo(tileX, tileY+.25*tileHeight) - gc.LineTo(tileX+.5*tileWidth, tileY) - gc.LineTo(tileX+tileWidth, tileY+.25*tileHeight) - gc.MoveTo(tileX+.5*tileWidth, tileY+.5*tileHeight) - gc.LineTo(tileX+.5*tileWidth, tileY+tileHeight) - gc.SetStrokeColor(tileColor) - gc.Stroke() + p.draw(gc, tileX, tileY, tileWidth, tileHeight, scale, palette) } } return draw2dimg.SaveToPngFile(path, im)