Documentation
¶
Overview ¶
package grid represents a 2d array of coordinates and their state as we build the mosaic. Its coordinates are divorced from the physical coordinate system. For instance, we treat all mosaics as the same grid coordinate system, regardless of whether we are building them top down, or from the top down, or from left to right. This grid abstracts away the physical dimensions of the bricks and allows us to concentrate on the core algorithm. This is handled via the Piece interface defined in piece.go.
In each orientation, a column of the grid has width equal to the smallest width piece, and a row is as high as the smallest height piece. For instance, if we are looking top down at a mosaic, each row and column is of equal size. If we are building a studs up mosaic, the row is equal in height to a single plate, and the column would be equal to the width of a single 1x1. If we are building a studs right mosaic, the row is equal to the width of a single 1x1 and the column would be equal to the height of a plate.
The grid is indexed such that [0][0] is the upper left corner and [numRows-1][numColumns-1] is the lower right corner.
Inventory is a convenience helper for determining how many pieces of which color are used in the model. This makes it easier to actually procure the pieces necessary to build the physical version of the model.
Package palette represents the colors of LEGO bricks. It defines sets of colors that will be used as the palette for creating the final mosaic (any color not in the palette will be ignored).
Package render is concerned with rendering Plans.
This file is responsible for rendering svg instructions of how to build a given plan.
Index ¶
- Variables
- func AddError(c color.Color, err QuantizationError) color.Color
- func ApproxSizeInch(size LDU) float32
- func ApproxSizeMm(size LDU) float32
- func AverageColor(si image.Image, bounds image.Rectangle) color.Color
- func BoundingBox(p Piece, origin Location) (minRow, minCol, maxRow, maxCol int)
- func CalculateRowsAndColumns(width, height, maxStuds int, orientation ViewOrientation) (rows, cols int)
- func DoRender(p Plan, canvas *svg.SVG)
- func GetDimensionsForBlock(o ViewOrientation) (width, height int)
- type AnchorPoint
- type Brick
- type BrickColor
- type BrickImage
- func (si *BrickImage) Bounds() image.Rectangle
- func (si *BrickImage) Color(row, col int) BrickColor
- func (si *BrickImage) ColorModel() color.Model
- func (si *BrickImage) IdealColor(row, col int) color.Color
- func (si *BrickImage) NumCols() int
- func (si *BrickImage) NumRows() int
- func (si *BrickImage) Orientation() ViewOrientation
- func (si *BrickImage) Paletted() *image.Paletted
- type By
- type ColorUsage
- type ColorUsages
- type Create
- type Grid
- func (g *Grid) Any(s State) bool
- func (g *Grid) Clone() Grid
- func (g *Grid) Fill(s State)
- func (g *Grid) Find(s State) []Location
- func (g *Grid) Get(row, col int) State
- func (g *Grid) PieceFits(extent []Location, loc Location) bool
- func (g *Grid) Set(row, col int, state State)
- func (g Grid) String() string
- type GridSolver
- type Ideal
- type IdealImage
- type Inventory
- type LDU
- type Location
- type MosaicPiece
- type Piece
- type PlacedBrick
- type Plan
- type Posterize
- type QuantizationError
- type RectPiece
- type Renderer
- type SVGRenderer
- type Solution
- type State
- type Usage
- type ViewOrientation
- type WriterRenderer
Constants ¶
This section is empty.
Variables ¶
var ( // OneByEight represents a 1 x 8 brick. See http://lego.wikia.com/wiki/Part_3008. OneByEight = brick{ // contains filtered or unexported fields } // OneBySix represents a 1 x 6 brick. See http://lego.wikia.com/wiki/Part_3009. OneBySix = brick{ // contains filtered or unexported fields } // OneByFour represents a 1 x 4 brick. See http://lego.wikia.com/wiki/Part_3010. OneByFour = brick{ // contains filtered or unexported fields } // OneByThree represents a 1 x 3 brick. See http://lego.wikia.com/wiki/Part_3622. OneByThree = brick{ // contains filtered or unexported fields } // OneByTwo represents a 1 x 2 brick. See http://lego.wikia.com/wiki/Part_3004. OneByTwo = brick{ // contains filtered or unexported fields } // OneByOne represents a 1 x 1 brick. See http://lego.wikia.com/wiki/Part_3005. OneByOne = brick{ // contains filtered or unexported fields } // TwoByEight represents a 2 x 8 brick. See http://lego.wikia.com/wiki/Part_3007. TwoByEight = brick{ // contains filtered or unexported fields } // TwoBySix represents a 2 x 6 brick. See http://lego.wikia.com/wiki/Part_2456. TwoBySix = brick{ // contains filtered or unexported fields } // TwoByFour represents a 2 x 4 brick. See http://lego.wikia.com/wiki/Part_3001. TwoByFour = brick{ // contains filtered or unexported fields } // TwoByThree represents a 2 x 3 brick. See http://lego.wikia.com/wiki/Part_3002. TwoByThree = brick{ // contains filtered or unexported fields } // TwoByTwo represents a 2 x 2 brick. See http://lego.wikia.com/wiki/Part_3003. TwoByTwo = brick{ // contains filtered or unexported fields } // OneByPlate represents a 1 x 1 plate. See http://lego.wikia.com/wiki/Part_3024. OneByOnePlate = brick{ // contains filtered or unexported fields } // OneByTwoPlate represents a 1 x 2 plate. See http://lego.wikia.com/wiki/Part_3023. OneByTwoPlate = brick{ // contains filtered or unexported fields } // OneByThreePlate represents a 1 x 3 plate. See http://lego.wikia.com/wiki/Part_3623. OneByThreePlate = brick{ // contains filtered or unexported fields } // OneByFourPlate represents a 1 x 4 plate. See http://lego.wikia.com/wiki/Part_3710. OneByFourPlate = brick{ // contains filtered or unexported fields } // OneBySixPlate represents a 1 x 6 plate. See http://lego.wikia.com/wiki/Part_3666. OneBySixPlate = brick{ // contains filtered or unexported fields } // OneByEightPlate represents a 1 x 8 plate. See http://brickowl.com/catalog/lego-plate-1-x-8-3460. OneByEightPlate = brick{ // contains filtered or unexported fields } // OneByTenPlate represents a 1 x 10 plate. See http://brickowl.com/catalog/lego-plate-1-x-10-4477. OneByTenPlate = brick{ // contains filtered or unexported fields } // Bricks represents a slice of all of the bricks (full height, not plates). They are listed in descending // order of area. Bricks = []Brick{ TwoByEight, TwoBySix, TwoByFour, TwoByThree, TwoByTwo, OneByEight, OneBySix, OneByFour, OneByThree, OneByTwo, OneByOne, } // Plates represents a slice of all of the standard plates (thinner than bricks). They are listed in // descending order of area. Plates = []Brick{ OneByTenPlate, OneByEightPlate, OneBySixPlate, OneByFourPlate, OneByThreePlate, OneByTwoPlate, OneByOnePlate, } // Pieces represents a slice of all of the standard Bricks; the concatenation of Bricks and Plates. Pieces = allBricks() )
var ( Red = color.RGBA{uint8(200), 0, 0, 0} // All color RGB values from // http://www.peeron.com/cgi-bin/invcgis/colorguide.cgi // cat ~/Dropbox/BrickColors.txt | awk '{print $2 " = BrickColor{name: \"" $2 "\", c:color.ARGB{R:uint8(" $7 "), G:uint8(" $8 "), B:uint8(" $9 "), A:uint8(0)}}"}' | mate White = BrickColor{/* contains filtered or unexported fields */} Grey = BrickColor{/* contains filtered or unexported fields */} LightYellow = BrickColor{/* contains filtered or unexported fields */} BrickYellow = BrickColor{/* contains filtered or unexported fields */} LightGreen = BrickColor{/* contains filtered or unexported fields */} LightReddishViolet = BrickColor{/* contains filtered or unexported fields */} LightOrangeBrown = BrickColor{/* contains filtered or unexported fields */} Nougat = BrickColor{/* contains filtered or unexported fields */} BrightRed = BrickColor{/* contains filtered or unexported fields */} MedReddishViolet = BrickColor{/* contains filtered or unexported fields */} BrightBlue = BrickColor{/* contains filtered or unexported fields */} BrightYellow = BrickColor{/* contains filtered or unexported fields */} EarthOrange = BrickColor{/* contains filtered or unexported fields */} Black = BrickColor{/* contains filtered or unexported fields */} DarkGrey = BrickColor{/* contains filtered or unexported fields */} DarkGreen = BrickColor{/* contains filtered or unexported fields */} MediumGreen = BrickColor{/* contains filtered or unexported fields */} LightYellowishOrange = BrickColor{/* contains filtered or unexported fields */} BrightGreen = BrickColor{/* contains filtered or unexported fields */} DarkOrange = BrickColor{/* contains filtered or unexported fields */} LightBluishViolet = BrickColor{/* contains filtered or unexported fields */} LightBlue = BrickColor{/* contains filtered or unexported fields */} LightRed = BrickColor{/* contains filtered or unexported fields */} MediumRed = BrickColor{/* contains filtered or unexported fields */} MediumBlue = BrickColor{/* contains filtered or unexported fields */} LightGrey = BrickColor{/* contains filtered or unexported fields */} BrightViolet = BrickColor{/* contains filtered or unexported fields */} BrightYellowishOrange = BrickColor{/* contains filtered or unexported fields */} BrightOrange = BrickColor{/* contains filtered or unexported fields */} BrightBluishGreen = BrickColor{/* contains filtered or unexported fields */} EarthYellow = BrickColor{/* contains filtered or unexported fields */} BrightBluishViolet = BrickColor{/* contains filtered or unexported fields */} MediumBluishViolet = BrickColor{/* contains filtered or unexported fields */} MedYellowishGreen = BrickColor{/* contains filtered or unexported fields */} MedBluishGreen = BrickColor{/* contains filtered or unexported fields */} LightBluishGreen = BrickColor{/* contains filtered or unexported fields */} BrYellowishGreen = BrickColor{/* contains filtered or unexported fields */} LigYellowishGreen = BrickColor{/* contains filtered or unexported fields */} MedYellowishOrange = BrickColor{/* contains filtered or unexported fields */} BrReddishOrange = BrickColor{/* contains filtered or unexported fields */} BrightReddishViolet = BrickColor{/* contains filtered or unexported fields */} LightOrange = BrickColor{/* contains filtered or unexported fields */} Gold = BrickColor{/* contains filtered or unexported fields */} DarkNougat = BrickColor{/* contains filtered or unexported fields */} Silver = BrickColor{/* contains filtered or unexported fields */} SandBlue = BrickColor{/* contains filtered or unexported fields */} SandViolet = BrickColor{/* contains filtered or unexported fields */} MediumOrange = BrickColor{/* contains filtered or unexported fields */} SandYellow = BrickColor{/* contains filtered or unexported fields */} EarthBlue = BrickColor{/* contains filtered or unexported fields */} EarthGreen = BrickColor{/* contains filtered or unexported fields */} SandBlueMetallic = BrickColor{/* contains filtered or unexported fields */} SandVioletMetallic = BrickColor{/* contains filtered or unexported fields */} SandYellowMetallic = BrickColor{/* contains filtered or unexported fields */} DarkGreyMetallic = BrickColor{/* contains filtered or unexported fields */} BlackMetallic = BrickColor{/* contains filtered or unexported fields */} LightGreyMetallic = BrickColor{/* contains filtered or unexported fields */} Sand = BrickColor{/* contains filtered or unexported fields */} SandRed = BrickColor{/* contains filtered or unexported fields */} DarkRed = BrickColor{/* contains filtered or unexported fields */} Gun = BrickColor{/* contains filtered or unexported fields */} Curry = BrickColor{/* contains filtered or unexported fields */} LemonMetalic = BrickColor{/* contains filtered or unexported fields */} FireYellow = BrickColor{/* contains filtered or unexported fields */} FlameYellowishOrange = BrickColor{/* contains filtered or unexported fields */} ReddishBrown = BrickColor{/* contains filtered or unexported fields */} FlameReddishOrange = BrickColor{/* contains filtered or unexported fields */} MediumStoneGrey = BrickColor{/* contains filtered or unexported fields */} RoyalBlue = BrickColor{/* contains filtered or unexported fields */} DarkRoyalBlue = BrickColor{/* contains filtered or unexported fields */} BrightReddishLilac = BrickColor{/* contains filtered or unexported fields */} DarkStoneGrey = BrickColor{/* contains filtered or unexported fields */} LightStoneGrey = BrickColor{/* contains filtered or unexported fields */} DarkCurry = BrickColor{/* contains filtered or unexported fields */} FadedGreen = BrickColor{/* contains filtered or unexported fields */} Turquoise = BrickColor{/* contains filtered or unexported fields */} LightRoyalBlue = BrickColor{/* contains filtered or unexported fields */} MediumRoyalBlue = BrickColor{/* contains filtered or unexported fields */} Rust = BrickColor{/* contains filtered or unexported fields */} Brown = BrickColor{/* contains filtered or unexported fields */} ReddishLilac = BrickColor{/* contains filtered or unexported fields */} Lilac = BrickColor{/* contains filtered or unexported fields */} LightLilac = BrickColor{/* contains filtered or unexported fields */} BrightPurple = BrickColor{/* contains filtered or unexported fields */} LightPurple = BrickColor{/* contains filtered or unexported fields */} LightPink = BrickColor{/* contains filtered or unexported fields */} LightBrickYellow = BrickColor{/* contains filtered or unexported fields */} WarmYellowishOrange = BrickColor{/* contains filtered or unexported fields */} CoolYellow = BrickColor{/* contains filtered or unexported fields */} DoveBlue = BrickColor{/* contains filtered or unexported fields */} MediumLilac = BrickColor{/* contains filtered or unexported fields */} Transparent = BrickColor{/* contains filtered or unexported fields */} TrRed = BrickColor{/* contains filtered or unexported fields */} TrLgBlue = BrickColor{/* contains filtered or unexported fields */} TrBlue = BrickColor{/* contains filtered or unexported fields */} TrYellow = BrickColor{/* contains filtered or unexported fields */} TrFluReddishOrange = BrickColor{/* contains filtered or unexported fields */} TrGreen = BrickColor{/* contains filtered or unexported fields */} TrFluGreen = BrickColor{/* contains filtered or unexported fields */} PhosphWhite = BrickColor{/* contains filtered or unexported fields */} TrBrown = BrickColor{/* contains filtered or unexported fields */} TrMediReddishViolet = BrickColor{/* contains filtered or unexported fields */} TrBrightBluishViolet = BrickColor{/* contains filtered or unexported fields */} NeonOrange = BrickColor{/* contains filtered or unexported fields */} NeonGreen = BrickColor{/* contains filtered or unexported fields */} TrFluBlue = BrickColor{/* contains filtered or unexported fields */} TrFluYellow = BrickColor{/* contains filtered or unexported fields */} TrFluRed = BrickColor{/* contains filtered or unexported fields */} RedFlipFlop = BrickColor{/* contains filtered or unexported fields */} YellowFlipFlop = BrickColor{/* contains filtered or unexported fields */} SilverFlipFlop = BrickColor{/* contains filtered or unexported fields */} FullPalette = color.Palette([]color.Color{ White, Grey, LightYellow, BrickYellow, LightGreen, LightReddishViolet, LightOrangeBrown, Nougat, BrightRed, MedReddishViolet, BrightBlue, BrightYellow, EarthOrange, Black, DarkGrey, DarkGreen, MediumGreen, LightYellowishOrange, BrightGreen, DarkOrange, LightBluishViolet, LightBlue, LightRed, MediumRed, MediumBlue, LightGrey, BrightViolet, BrightYellowishOrange, BrightOrange, BrightBluishGreen, EarthYellow, BrightBluishViolet, MediumBluishViolet, MedYellowishGreen, MedBluishGreen, LightBluishGreen, BrYellowishGreen, LigYellowishGreen, MedYellowishOrange, BrReddishOrange, BrightReddishViolet, LightOrange, Gold, DarkNougat, Silver, SandBlue, SandViolet, MediumOrange, SandYellow, EarthBlue, EarthGreen, SandBlueMetallic, SandVioletMetallic, SandYellowMetallic, DarkGreyMetallic, BlackMetallic, LightGreyMetallic, Sand, SandRed, DarkRed, Gun, Curry, LemonMetalic, FireYellow, FlameYellowishOrange, ReddishBrown, FlameReddishOrange, MediumStoneGrey, RoyalBlue, DarkRoyalBlue, BrightReddishLilac, DarkStoneGrey, LightStoneGrey, DarkCurry, FadedGreen, Turquoise, LightRoyalBlue, MediumRoyalBlue, Rust, Brown, ReddishLilac, Lilac, LightLilac, BrightPurple, LightPurple, LightPink, LightBrickYellow, WarmYellowishOrange, CoolYellow, DoveBlue, MediumLilac, Transparent, TrRed, TrLgBlue, TrBlue, TrYellow, TrFluReddishOrange, TrGreen, TrFluGreen, PhosphWhite, TrBrown, TrMediReddishViolet, TrBrightBluishViolet, NeonOrange, NeonGreen, TrFluBlue, TrFluYellow, TrFluRed, RedFlipFlop, YellowFlipFlop, SilverFlipFlop, }) LimitedPalette = color.Palette([]color.Color{ White, Grey, Black, BrightRed, BrightBlue, BrightYellow, DarkGrey, }) GrayPlusPalette = color.Palette([]color.Color{ White, Grey, Black, DarkGrey, LightGrey, DarkStoneGrey, EarthGreen, DarkStoneGrey, LightStoneGrey, BrightRed, BrightBlue, BrightYellow, }) GrayScalePalette = color.Palette([]color.Color{ White, Black, DarkGrey, LightGrey, DarkStoneGrey, }) Primary = color.Palette([]color.Color{ BrightYellow, BrightRed, BrightBlue, }) BlackAndWhite = color.Palette([]color.Color{ White, Black, }) )
Functions ¶
func AddError ¶
func AddError(c color.Color, err QuantizationError) color.Color
AddError adds the given amount of error to the given color, transforming it into a new color. For instance, if c is {R:100, G:100, B:100} and error is {r:-50,g:50,b:-50}, then the final result is {R:50, G:150, B:50}
func ApproxSizeInch ¶
func ApproxSizeMm ¶
func AverageColor ¶
AverageColor determines the 'average' color of the subimage whose coordinates are contained in the given bounds. The average is an arithmetic average in RGB color space. TODO(ndunn): try different color spaces.
func BoundingBox ¶
Upper left origin
func CalculateRowsAndColumns ¶
func CalculateRowsAndColumns(width, height, maxStuds int, orientation ViewOrientation) (rows, cols int)
func DoRender ¶
func DoRender(p Plan, canvas *svg.SVG)
DoRender writes the plan information to the svg canvas.
func GetDimensionsForBlock ¶
func GetDimensionsForBlock(o ViewOrientation) (width, height int)
Types ¶
type AnchorPoint ¶
type AnchorPoint int
const ( UpperLeft AnchorPoint = iota UpperRight LowerRight LowerLeft )
func (AnchorPoint) String ¶
func (a AnchorPoint) String() string
type Brick ¶
type Brick interface { Name() string Id() string Width() int Length() int Height() int // TODO(ndunn): This somehow has to take into account color // Cost in cents. ApproximateCost() int }
Brick represents a prototypical piece, not bound to any specific orientation or color.
type BrickColor ¶
type BrickColor struct {
// contains filtered or unexported fields
}
BrickColor represents the color of a LEGO brick. It implements the color.Color interface via delegation.
func ColorForName ¶
func ColorForName(n string) *BrickColor
ColorForName returns the BrickColor whose name matches n, or nil.
func (BrickColor) RGBA ¶
func (c BrickColor) RGBA() (r, g, b, a uint32)
type BrickImage ¶
type BrickImage struct { // Frames are snapshots of the process of creating the final image, for debuggin // purposes Frames []*image.Paletted // contains filtered or unexported fields }
BrickImage is an implementation of Ideal interface.
func NewBrickImage ¶
func NewBrickImage(img image.Image, rows, cols int, palette color.Palette, o ViewOrientation, errorScalingFactor float32) *BrickImage
NewBrickImage returns a BrickImage based on the given inputs.
func (*BrickImage) Bounds ¶
func (si *BrickImage) Bounds() image.Rectangle
FIXME ndunn base it on the orientation
func (*BrickImage) Color ¶
func (si *BrickImage) Color(row, col int) BrickColor
Color returns the best palette.BrickColor for the given row/column in the image based on the palette this image was instantiated with.
func (*BrickImage) ColorModel ¶
func (si *BrickImage) ColorModel() color.Model
func (*BrickImage) IdealColor ¶
func (si *BrickImage) IdealColor(row, col int) color.Color
IdealColor returns the color that ideally we would use for the row / col combination if we had pieces of every color. Later this will be quantized into the nearest neighbor, into a BrickColor.
func (*BrickImage) NumCols ¶
func (si *BrickImage) NumCols() int
NumRows returns the number of columns in the piece.
func (*BrickImage) NumRows ¶
func (si *BrickImage) NumRows() int
NumRows returns the number of rows in the piece.
func (*BrickImage) Orientation ¶
func (si *BrickImage) Orientation() ViewOrientation
Orientation returns the way in which the image is oriented.
func (*BrickImage) Paletted ¶
func (si *BrickImage) Paletted() *image.Paletted
Paletted renders the current state of the image as a Paletted image. Useful for debugging purposes
type By ¶
TODO(ndunn): finish this, sort by price, size (number of grid lcoations it takes up) By is the type of a "less" function that defines the ordering of its Piece pieces
type ColorUsage ¶
type ColorUsage struct {
// contains filtered or unexported fields
}
type ColorUsages ¶
type ColorUsages []ColorUsage
func (ColorUsages) Len ¶
func (c ColorUsages) Len() int
func (ColorUsages) Less ¶
func (c ColorUsages) Less(i, j int) bool
func (ColorUsages) Swap ¶
func (c ColorUsages) Swap(i, j int)
type Create ¶
Create is the interface by which we convert Ideal mosaics into a plan for building it. As discussed in Plan, different Creators might build Plans that do not perfectly match the Ideal.
type Grid ¶
Grid is an abstract representation of the mosaic to assemble.
func WithState ¶
WithState is a convenience function for creating a grid whose contents are entirely filled with state s.
func (*Grid) Find ¶
Find returns all of the locations that have the given state, in row major order.
func (*Grid) Get ¶
Get returns the state at row, col in the given grid. If the given row, col arguments are out of bounsd, the method returns Empty.
func (*Grid) PieceFits ¶
PieceFits determines if the given piece can fit at the desired location in the grid, where loc is the upper left hand corner of the piece. Note that orientation is already baked into the Extent() of the piece, which is why it is not an argument to this method.
type GridSolver ¶
type GridSolver func(g *Grid, pieces []MosaicPiece) (Solution, error)
GridSolver is the interface for fitting pieces into the given grid.
type Ideal ¶
type Ideal interface { Orientation() ViewOrientation NumRows() int NumCols() int Color(row, col int) BrickColor }
Ideal is the idealized grid of how the mosaic should look. Basically a 2d grid of color.
func DitherPosterize ¶
DitherPosterize converts the given image into an Ideal form using a standard amount of dithering (error propagation).
func EucPosterize ¶
EucPosterize returns an Ideal representation of the image with no dithering.
type IdealImage ¶
IdealImage is an object that implements both the Image interface and the Ideal interface
type Inventory ¶
type Inventory struct {
// contains filtered or unexported fields
}
func MakeInventory ¶
func MakeInventory() Inventory
func (*Inventory) Add ¶
func (inventory *Inventory) Add(c BrickColor, p Brick)
func (*Inventory) ApproximateCost ¶
ApproximateCost estimates how much the mosaic will cost to build, given the price information embedded in the pieces. Returns a value in cents.
func (Inventory) DescendingUsage ¶
func (inventory Inventory) DescendingUsage() []ColorUsage
func (Inventory) PiecesForColor ¶
func (inv Inventory) PiecesForColor(c BrickColor) []Brick
func (Inventory) UsageForColorMap ¶
func (inventory Inventory) UsageForColorMap() map[BrickColor]Usage
type Location ¶
type Location struct {
Row, Col int
}
Location represents one cell in the grid.
func Translate ¶
func Translate(locs []Location, pt AnchorPoint) []Location
func TranslateAbsoluteOrigin ¶
func TranslateAbsoluteOrigin(absLoc Location, p MosaicPiece, pt AnchorPoint) Location
type MosaicPiece ¶
MosaicPiece represents a given physical brick in a certain orientation, which determines its extent in the 2d grid.
func PiecesForOrientation ¶
func PiecesForOrientation(o ViewOrientation, pieces []Brick) []MosaicPiece
func StudsOutPiece ¶
func StudsOutPiece(piece Brick) MosaicPiece
TODO(ndunn): This could either be facing horizontally or vertically. This is not taking that into consideration.
func StudsRightPiece ¶
func StudsRightPiece(piece Brick) MosaicPiece
func StudsTopPiece ¶
func StudsTopPiece(piece Brick) MosaicPiece
type Piece ¶
type Piece interface {
Extent() []Location
}
Piece is the virtual representation of a physical brick. By abstracting out the orientation of the brick in real world space, it allows us to use the same algorithm for creating mosaics (solving grids) in any orientation.
For instance, say that we have a physical 2x4 brick. Depending on which way we orient the brick, it has different dimensions in the grid. If it is placed studs up, it is 3 plates (3 rows) high and 4 studs (4 columns) wide. This would be represented by a RectPiece with 3 rows and 4 columns, and its extent would be given by (0, 0), (0, 1), (0, 2), (0, 3) (1, 0), (1, 1), (1, 2), (1, 3) (2, 0), (2, 1), (2, 2), (2, 3).
In picture form:
+--+ +--+ +--+ +--+
+--+--+---+--+---+--+-- +--+--+ + | | | | | | | | | 3 plates high | | | | | | | | | +-----------------------------+ +
+-----------------------------+
4 studs wide
Say that we instead are looking down on the brick and building our mosaics that way, with the studs facing out towards the viewer. We can orient this in two directions - vertically or horizontally. In the vertical case, we would say that the Piece has 4 rows (4 studs) and 2 columns (2 studs).
+--------------+ | | | +--+ +--+ | | | | | | | | +--+ +--+ | | | | +--+ +--+ | | | | | | | | +--+ +--+ | | | | +--+ +--+ | | | | | | | | +--+ +--+ | | | | +--+ +--+ | | | | | | | | +--+ +--+ | | | +--------------+
In the horizontal case it's 2 rows (2 studs) and 4 columns (4 studs).
Note that the physical meaning of the dimension of each cell in the grid is dependent upon the orientation of the pieces, but completely unnecessary in the algorithm of filling in the pieces.
type PlacedBrick ¶
type PlacedBrick struct { // Unique identifier for this brick within the mosaic Id int // Upper left corner of the piece Origin Location // The relative locations of how big this brick is. Add to origin to get absolute // location Locs []Location // What color is this brick? Color BrickColor // Characteristics of the brick - 2x4, etc Shape Brick // Orientation represents how the brick is placed in the mosaic Orientation ViewOrientation }
PlacedBrick represents a physical brick placed within the mosaic, at a certain location, with a certain color, orientation, and shape.
func (PlacedBrick) Extent ¶
func (p PlacedBrick) Extent() []Location
type Plan ¶
type Plan interface { Orig() Ideal Pieces() []PlacedBrick Piece(row, col int) PlacedBrick Inventory() Inventory }
Plan represents how to build the mosaic. The resulting plan may not match the Ideal perfectly; for instance, an implementation might decide to depart slightly from the desired colors if it leads to enhanced rigidity in the structure.
func CreateGridMosaic ¶
func CreateGridMosaic(m Ideal, solver GridSolver) Plan
CreateGridMosaic converts an Ideal representation of the mosaic into a plan for building the mosaic. In other words, it picks the pieces to use and where to place them according to the logic in the GridSolver implementation.
type Posterize ¶
type Posterize func(img image.Image, p color.Palette, rows int, cols int, o ViewOrientation) IdealImage
Posterize is the interface for converting from images into DesiredMosaic objects.
type QuantizationError ¶
type QuantizationError struct {
// contains filtered or unexported fields
}
QuantizationError represents an error between a desired color and the best possible color that we can use to represent it.
func Error ¶
func Error(oldC, newC color.Color) QuantizationError
Error returns how much error is there from c1 relative to c0? High numbers means c1 has higher in that channel.
func (QuantizationError) Scale ¶
func (e QuantizationError) Scale(factor float32) QuantizationError
Scale scales the given error by the given factor. For instance, Scale(2.0) doubles the error, while Scale(.5) halves it. This returns a new object.
type Renderer ¶
Renderers somehow convert the plan into a form that's easy for humans to build. For instance it might render the plan as an SVG file embedded in a webpage, or print it to standard out, or render it as LDRAW instructions.
type SVGRenderer ¶
type SVGRenderer struct{}
func (SVGRenderer) Render ¶
func (r SVGRenderer) Render(p Plan) string
type Solution ¶
type Solution struct { Original Grid Pieces map[Location]MosaicPiece }
Solution encapsulates the original requested grid to solve, as well as the solution to that grid, mapping location to the brick that goes there.
func GreedySolve ¶
func GreedySolve(g *Grid, pieces []MosaicPiece) (Solution, error)
Solve attempts to solve the grid by filling in the missing pieces. The pieces are considered in the order defined in the pieces list. They should be sorted accordingly, with the best entry first in the list (i.e.. least expensive). If the given pieces cannot exactly match the missing pieces, returns a non nil error
func SymmetricalGreedySolve ¶
func SymmetricalGreedySolve(g *Grid, pieces []MosaicPiece) (Solution, error)
type State ¶
type State int
State is an enum representing the state of a location in the grid.
const ( // Empty indicates that nothing is in the grid location, nor should there be. Empty State = iota // ToBeFilled indicates that there is nothing currently in the grid location, but there should be. ToBeFilled State = Empty + 1 // Filled indicates that there is already something in the grid location. Filled State = ToBeFilled + 1 )
type ViewOrientation ¶
type ViewOrientation int
ViewOrientation represents the orientation of each brick in the mosaic.
const ( // StudsOut is a top down view, studs facing out towards viewer. Rows and columns refer to equal distances. StudsOut ViewOrientation = iota // StudsTop indicates a view from the side - pieces build on top of each other. Rows refer to plate height, // columns are 1x1 width. StudsTop // StudsRight indicates a view from the side, where the top of a piece faces to the right. Rows refer to // piece width, columns are plate height. StudsRight )
type WriterRenderer ¶
type WriterRenderer struct {
// contains filtered or unexported fields
}
TerminalRenderer is an implementation of the Renderer interface which emits a textual representation of the Plan to stdout.
func (*WriterRenderer) Render ¶
func (t *WriterRenderer) Render(p Plan) string