package grid
import "github.com/anaseto/grid"
package grid provides a generic two-dimensional matrix slice type.
The package provides utilities for iterating such grids, as well as manipulating positions and ranges.
The API is inspired by the standard Go slice builtin functions and the image standard package.
Index ¶
- type Grid
- func NewGrid[T any](w, h int) Grid[T]
- func NewGridFromSlice[T any](s []T, w int) Grid[T]
- func (gd Grid[T]) At(p Point) T
- func (gd Grid[T]) AtU(p Point) T
- func (gd Grid[T]) Bounds() Range
- func (gd Grid[T]) Cap() Point
- func (gd Grid[T]) Contains(p Point) bool
- func (gd Grid[T]) Contents() []T
- func (gd Grid[T]) Copy(src Grid[T]) Point
- func (gd Grid[T]) Fill(c T)
- func (gd Grid[T]) FillFunc(fn func(Point) T)
- func (gd Grid[T]) Iter(fn func(Point, T))
- func (gd Grid[T]) Iterator() GridIterator[T]
- func (gd Grid[T]) Map(fn func(Point, T) T)
- func (gd Grid[T]) Range() Range
- func (gd Grid[T]) Resize(w, h int) Grid[T]
- func (gd Grid[T]) Set(p Point, c T)
- func (gd Grid[T]) Size() Point
- func (gd Grid[T]) Slice(rg Range) Grid[T]
- type GridIterator
- func (it *GridIterator[T]) Next() bool
- func (it *GridIterator[T]) P() Point
- func (it *GridIterator[T]) Reset()
- func (it *GridIterator[T]) SetP(p Point)
- func (it *GridIterator[T]) SetV(c T)
- func (it *GridIterator[T]) V() T
- type Point
- func (p Point) Add(q Point) Point
- func (p Point) Div(k int) Point
- func (p Point) In(rg Range) bool
- func (p Point) Mul(k int) Point
- func (p Point) Shift(x, y int) Point
- func (p Point) String() string
- func (p Point) Sub(q Point) Point
- type Range
- func NewRange(x0, y0, x1, y1 int) Range
- func (rg Range) Add(p Point) Range
- func (rg Range) Column(x int) Range
- func (rg Range) Columns(x0, x1 int) Range
- func (rg Range) Empty() bool
- func (rg Range) Eq(r Range) bool
- func (rg Range) In(r Range) bool
- func (rg Range) Intersect(r Range) Range
- func (rg Range) Iter(fn func(Point))
- func (rg Range) Line(y int) Range
- func (rg Range) Lines(y0, y1 int) Range
- func (rg Range) Overlaps(r Range) bool
- func (rg Range) Shift(x0, y0, x1, y1 int) Range
- func (rg Range) Size() Point
- func (rg Range) String() string
- func (rg Range) Sub(p Point) Range
- func (rg Range) Union(r Range) Range
Examples ¶
Types ¶
type Grid ¶
type Grid[T any] struct { // contains filtered or unexported fields }
Grid represents a two-dimensional matrix of values of any type. It is a slice type, so it represents a rectangular range within an underlying original grid. Due to how it is represented internally, it is more efficient to iterate in row-major order, as in the following pattern:
max := gd.Size()
for y := 0; y < max.Y; y++ {
for x := 0; x < max.X; x++ {
p := Point{X: x, Y: y}
// do something with p and the grid gd
}
}
Most iterations can be performed using the Slice, Fill, Copy, Map and Iter methods. An alternative choice is to use the Iterator method.
Grid elements must be created with NewGrid.
Code:play
Output:Example¶
package main
import (
"fmt"
"github.com/anaseto/grid"
)
func main() {
// Create a new 10x10 grid of runes.
gd := grid.NewGrid[rune](10, 10)
// Fill the whole grid with dots.
gd.Fill('.')
// Define a range (3,3)-(7,7).
rg := grid.NewRange(3, 3, 7, 7)
// Define a slice of the grid using the range.
rectangle := gd.Slice(rg)
// Fill the rectangle with #.
rectangle.Fill('#')
// Print the grid.
it := gd.Iterator()
max := gd.Size()
for it.Next() {
fmt.Printf("%c", it.V())
if it.P().X == max.X-1 {
fmt.Print("\n")
}
}
}
..........
..........
..........
...####...
...####...
...####...
...####...
..........
..........
..........
func NewGrid ¶
NewGrid returns a new grid with given width and height in cells. The width and height should be positive or null. The new grid contains all positions (X,Y) with 0 <= X < w and 0 <= Y < h. The grid is filled with the zero value for cells.
func NewGridFromSlice ¶
NewGridFromSlice builds a grid of width w with initial contents provided by slice s. The slice's length should be a multiple of w. The slice's values are used in row-major order.
func (Grid[T]) At ¶
At returns the cell at a given position. If the position is out of range, it returns the zero value.
func (Grid[T]) AtU ¶
AtU returns the cell at a given position without checking the grid slice bounds. If the position is out of bounds, it returns a value corresponding to the position in the underlying grid, or the zero value if also out of the underlying grid's range.
It may be somewhat faster than At in tight loops, but most of the time you can get the same performance using GridIterator or iteration functions, which are less error-prone.
func (Grid[T]) Bounds ¶
Bounds returns the range that is covered by this grid slice within the underlying original grid.
func (Grid[T]) Cap ¶
Cap returns the size (w,h) measuring the grid and the available space past it within the underlying whole grid. In other words, gd.Bounds().Min.Add(Point{x,y}) is the size of the underlying grid.
func (Grid[T]) Contains ¶
Contains returns true if the given relative position is within the grid.
func (Grid[T]) Contents ¶
func (gd Grid[T]) Contents() []T
Contents returns the grid's current underlying slice with the values of the whole underlying grid, in row-major order.
func (Grid[T]) Copy ¶
Copy copies elements from a source grid src into the destination grid gd, and returns the copied grid-slice size, which is the minimum of both grids for each dimension. The result is independent of whether the two grids referenced memory overlaps or not.
func (Grid[T]) Fill ¶
func (gd Grid[T]) Fill(c T)
Fill sets the given cell as content for all the grid positions.
func (Grid[T]) FillFunc ¶
FillFunc updates the content for all the grid positions, in row-major order, using the given function return value.
func (Grid[T]) Iter ¶
Iter iterates a function on all the grid positions and cells, in row-major order.
func (Grid[T]) Iterator ¶
func (gd Grid[T]) Iterator() GridIterator[T]
Iterator returns an iterator that can be used to iterate on the grid. It may be convenient when more flexibility than the provided by the other iteration functions is needed. It is used as follows:
it := gd.Iterator()
for it.Next() {
// call it.P() or it.Cell() or it.SetCell() as appropriate
}
func (Grid[T]) Map ¶
Map updates the grid content using the given mapping function. The iteration is done in row-major order.
func (Grid[T]) Range ¶
Range returns the range with Min set to (0,0) and Max set to gd.Size(). It may be convenient when using Slice with a range Shift.
func (Grid[T]) Resize ¶
Resize is similar to Slice, but it only specifies new dimensions, and if the range goes beyond the underlying original grid range, it will grow the underlying grid. It preserves the content, and any new cells get the zero value.
func (Grid[T]) Set ¶
Set draws a cell at a given position in the grid. If the position is out of range, the function does nothing.
func (Grid[T]) Size ¶
Size returns the grid (width, height) in cells, and is a shorthand for gd.Range().Size().
func (Grid[T]) Slice ¶
Slice returns a rectangular slice of the grid given by a range relative to the grid. If the range is out of bounds of the parent grid, it will be reduced to fit to the available space. The returned grid shares memory with the parent.
type GridIterator ¶
type GridIterator[T any] struct { // contains filtered or unexported fields }
GridIterator represents a stateful iterator for a grid. They are created
with the Iterator method.
Code:play
Output:Example¶
package main
import (
"fmt"
"github.com/anaseto/grid"
)
func main() {
// Create a new 26x2 grid of runes.
gd := grid.NewGrid[rune](26, 2)
// Get an iterator.
it := gd.Iterator()
// Iterate on the grid and fill it with successive alphabetic
// characters.
r := 'a'
max := gd.Size()
for it.Next() {
it.SetV(r)
r++
if it.P().X == max.X-1 {
r = 'A'
}
}
// Print the grid.
it.Reset()
for it.Next() {
fmt.Printf("%c", it.V())
if it.P().X == max.X-1 {
fmt.Print("\n")
}
}
}
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
func (*GridIterator[T]) Next ¶
func (it *GridIterator[T]) Next() bool
Next advances the iterator the next position in the grid, using row-major ordering.
func (*GridIterator[T]) P ¶
func (it *GridIterator[T]) P() Point
P returns the iterator's current position.
func (*GridIterator[T]) Reset ¶
func (it *GridIterator[T]) Reset()
Reset resets the iterator's state so that it can be used again.
func (*GridIterator[T]) SetP ¶
func (it *GridIterator[T]) SetP(p Point)
SetP sets the iterator's current position.
func (*GridIterator[T]) SetV ¶
func (it *GridIterator[T]) SetV(c T)
SetV updates cell value at the iterator's current position. It's faster than calling Set on the grid.
func (*GridIterator[T]) V ¶
func (it *GridIterator[T]) V() T
V returns the cell value at the iterator's current position.
type Point ¶
Point represents an (X,Y) position in a grid.
It follows conventions similar to the ones used by the standard library image.Point.
func (Point) Add ¶
Add returns vector p+q.
func (Point) Div ¶
Div returns the vector p/k.
func (Point) In ¶
In reports whether the position is within the given range.
func (Point) Mul ¶
Mul returns the vector p*k.
func (Point) Shift ¶
Shift returns a new point with coordinates shifted by (x,y). It's a shorthand for p.Add(Point{x,y}).
func (Point) String ¶
String returns a string representation of the form "(x,y)".
func (Point) Sub ¶
Sub returns vector p-q.
type Range ¶
type Range struct {
Min, Max Point
}
Range represents a rectangle in a grid that contains all the positions P such that Min <= P < Max coordinate-wise. A range is well-formed if Min <= Max. When non-empty, Min represents the upper-left position in the range, and Max-(1,1) the lower-right one.
It follows conventions similar to the ones used by the standard library image.Rectangle.
func NewRange ¶
NewRange returns a new Range with coordinates (x0, y0) for Min and (x1, y1) for Max. The returned range will have minimum and maximum coordinates swapped if necessary, so that the range is well-formed.
func (Range) Add ¶
Add returns a range of same size translated by +p.
func (Range) Column ¶
Column reduces the range to relative column x, or an empty range if out of bounds.
func (Range) Columns ¶
Columns reduces the range to relative columns between x0 (included) and x1 (excluded), or an empty range if out of bounds.
func (Range) Empty ¶
Empty reports whether the range contains no positions.
func (Range) Eq ¶
Eq reports whether the two ranges contain the same set of points. All empty ranges are considered equal.
func (Range) In ¶
In reports whether range rg is completely contained in range r.
func (Range) Intersect ¶
Intersect returns the largest range contained both by rg and r. If the two ranges do not overlap, the zero range will be returned.
func (Range) Iter ¶
Iter calls a given function for all the positions of the range.
func (Range) Line ¶
Line reduces the range to relative line y, or an empty range if out of bounds.
func (Range) Lines ¶
Lines reduces the range to relative lines between y0 (included) and y1 (excluded), or an empty range if out of bounds.
func (Range) Overlaps ¶
Overlaps reports whether the two ranges have a non-zero intersection.
func (Range) Shift ¶
Shift returns a new range with coordinates shifted by (x0,y0) and (x1,y1).
func (Range) Size ¶
Size returns the (width, height) of the range in cells.
func (Range) String ¶
String returns a string representation of the form "(x0,y0)-(x1,y1)".
func (Range) Sub ¶
Sub returns a range of same size translated by -p.
func (Range) Union ¶
Union returns the smallest range containing both rg and r.
Source Files ¶
- Version
- v0.2.0 (latest)
- Published
- Dec 22, 2021
- Platform
- linux/amd64
- Imports
- 1 packages
- Last checked
- 8 months ago –
Tools for package owners.