Module forma.pattern
A class containing a set or pattern of cells.
The pattern class is the central class of forma
, representing a set of
points or cells. This set can be initialised as empty, or according to a
'prototype' consisting of a NxM table matrix of 1's or 0's. Several helper
methods for the initialisation of a pattern are provided in the
primitives module. Once initialised, a pattern can only be modified by
the insert method, used to add active cells. All other pattern
manipulations return a new, modified pattern rather than modifying patterns
in-place.
Several pattern manipulators are provided here. For example a shift manipulator which shifts the coordinates of an entire pattern, manipulators that enlarge a pattern by a scale factor and modifiers than can rotate or reflect patterns in the x (hreflect) or y (vreflect) axes. Particuarly useful are manipulators which generate new patterns such as the edge (outer hull) or surface (inner-hull) of other patterns. These manipulators can be used with custom definitions of a cell's neighbourhood.
Pattern coordinates should be reliable in [-65536, 65536]. This is
adjustable through the MAX_COORDINATE
constant.
Through an abuse of metatables, all functions can be used either 'procedurally' as
pattern.method(input_pattern, ... )
or as a class method
input_pattern:method(...)
Usage:
-- 'Procedural' style pattern creation local p1 = pattern.new() pattern.insert(p1, 1,1) -- 'Method' style with chaining used for :insert local p2 = pattern.new():insert(1,1) -- Idential as to p1 -- 'Prototype' style local p3 = pattern.new({{1,1,1}, {1,0,1}, {1,1,1}}) -- Fetch a random cell and the medoid (centre-of-mass) cell from a pattern local random_cell = p1:rcell() local medoid_cell = p1:medoid() -- Compute the outer (outside the existing pattern) hull -- Using 8-direction (Moore) neighbourhood local outer_hull = p1:edge(neighbourhood.moore()) -- or equivalently outer_hull = pattern.edge(p1, neighbourhood.moore())
Basic methods
new (prototype) | Pattern constructor. |
clone (ip) | Copy an existing pattern. |
insert (ip, x, y) | Insert a new cell into a pattern. |
has_cell (ip, x, y) | Check if a cell is active in a pattern. |
cell_list (ip) | Return a list of cells active in the pattern. |
size (ip) | Return the number of cells active in a pattern. |
size_sort (pa, pb) | Size comparator for two patterns. |
edit_distance (a, b) | Return the total number of differing cells between two patterns. |
Iterators
cells (ip) | Iterator over active cells in the pattern. |
cell_coordinates (ip) | Iterator over active cell coordinates in the pattern. |
shuffled_cells (ip, rng) | Shuffled iterator over active cells in the pattern. |
shuffled_coordinates (ip, rng) | Shuffled iterator over active cell coordinates in the pattern. |
Metamethods
__tostring (ip) | Render pattern as a string. |
__add (a, b) | Add two patterns to each other. |
__sub (a, b) | Subtract one pattern from another. |
__eq (a, b) | Pattern equality test. |
Pattern cell selectors
rcell (ip, rng) | Pattern random cell method. |
centroid (ip) | Compute the centroid of a pattern. |
medoid (ip, measure) | Compute the medoid cell of a pattern. |
Pattern manipulators
shift (ip, sx, sy) | Generate a copy of a pattern shifted by a vector(x,y) |
normalise (ip) | Copy a pattern, shifting its origin to (0,0). |
enlarge (ip, f) | Generate an enlarged version of a pattern. |
rotate (ip) | Rotate a pattern by 90° clockwise about the origin |
vreflect (ip) | Generate a copy of a pattern, mirroring it vertically. |
hreflect (ip) | Generate a copy of a pattern, mirroring it horizontally. |
edge (ip, nbh) | Generate a pattern consisting of all cells on the edge of a provided pattern. |
surface (ip, nbh) | Generate a pattern consisting of cells on the surface of a provided pattern. |
intersection (...) | Generate a pattern consisting of the overlapping intersection of existing patterns |
sum (...) | Generate a pattern consisting of the sum of existing patterns |
Packing methods
packtile (a, b) | Returns a cell where pattern a overlaps with pattern b . |
packtile_centre (a, b) | Center-weighted version of pattern.packtile. |
Test methods
get_max_coordinate () | Returns the maximum hashable coordinate. |
test_coordinate_map (x, y) | Test the coordinate transform between (x,y) and spatial hash. |
Basic methods
- new (prototype)
-
Pattern constructor.
This method returns a new pattern, according to a prototype. If no
prototype is used, then an empty pattern is returned. For example, if
called with the prototype
{{1,0},{0,1}}
this method will return the pattern:10 01
Parameters:
- prototype (optional) an N*M 2D table of ones and zeros
Returns:
-
a new pattern according to the prototype
- clone (ip)
-
Copy an existing pattern.
Parameters:
- ip input pattern for cloning
Returns:
-
a copy of the pattern ip
- insert (ip, x, y)
-
Insert a new cell into a pattern.
Re-returns the provided cell to enable cascading.
e.g
pattern.new():insert(x,y)
returns a pattern with a single cell at (x,y).Parameters:
- ip pattern for cell insertion
- x first coordinate of new cell
- y second coordinate of new cell
Returns:
-
ip for method cascading
- has_cell (ip, x, y)
-
Check if a cell is active in a pattern.
This has fewer checks than usual as it's a common inner-loop call.
Parameters:
- ip pattern for cell check
- x first coordinate of cell to be returned
- y second coordinate of cell to be returned
Returns:
-
True if pattern
ip
includes the cell at (x,y), False otherwise - cell_list (ip)
-
Return a list of cells active in the pattern.
Parameters:
- ip source pattern for active cell list.
- size (ip)
-
Return the number of cells active in a pattern.
Parameters:
- ip pattern for size check
- size_sort (pa, pb)
-
Size comparator for two patterns.
Useful for table.sort to rank patterns by size (number of cells)
Parameters:
- pa the first pattern for comparison
- pb the second pattern for comparison
Returns:
-
pa:size() > pb:size()
- edit_distance (a, b)
-
Return the total number of differing cells between two patterns.
Parameters:
- a first pattern for edit distance calculation
- b second pattern for edit distance calculation
Iterators
- cells (ip)
-
Iterator over active cells in the pattern.
Parameters:
- ip source pattern for active cell iterator
Returns:
-
an iterator returning a cell for every active cell in the pattern
Usage:
local ipattern = primitives.square(10) for icell in ipattern:cells() do print(icell.x, icell.y) end
- cell_coordinates (ip)
-
Iterator over active cell coordinates in the pattern.
Simmilar to pattern.cells but provides an iterator that runs over (x,y)
coordinates instead of cell instances. Normally faster than
pattern.cells as no tables are created here.
Parameters:
- ip source pattern for active cell iterator
Returns:
-
an iterator returning active cell (x,y) coordinates
Usage:
local ipattern = primitives.square(10) for ix, iy in ipattern:cell_coordinates() do print(ix, iy) end
- shuffled_cells (ip, rng)
-
Shuffled iterator over active cells in the pattern.
Simmilar to pattern.cells but provides an iterator that returns cells in a
randomised order, according to a provided random number generator. See
pattern.cells for usage.
Parameters:
- ip source pattern for active cell iterator
- rng (optional) A random number generating table, following the signature of math.random
Returns:
-
an iterator returning a cell for every active cell in the pattern, in a randomised order
- shuffled_coordinates (ip, rng)
-
Shuffled iterator over active cell coordinates in the pattern.
Simmilar to pattern.cell_coordinates but returns cell (x,y) coordinates in
a randomised order according to a provided random number generator. See
pattern.cell_coordinates for usage.
Parameters:
- ip source pattern for active cell iterator
- rng (optional) A random number generating table, following the signature of math.random
Returns:
-
an iterator returning active cell (x,y) coordinates, randomly shuffled
Metamethods
- __tostring (ip)
-
Render pattern as a string.
Prints the stored pattern to string, rendered using the character stored in
pattern.onchar for activated cells and pattern.offchar for unactivated cells.
Parameters:
- ip The pattern to be rendered as a string
Returns:
-
pattern as string
- __add (a, b)
-
Add two patterns to each other.
Parameters:
- a first pattern to be added
- b second pattern to be added
Returns:
-
New pattern consisting of the superset of patterns a and b
- __sub (a, b)
-
Subtract one pattern from another.
Parameters:
- a base pattern
- b pattern to be subtracted from a
Returns:
-
New pattern consisting of the subset of cells in a which are not in b
- __eq (a, b)
-
Pattern equality test.
Parameters:
- a first pattern for equality check
- b second pattern for equality check
Returns:
-
true if patterns are identical, false if not
Pattern cell selectors
- rcell (ip, rng)
-
Pattern random cell method.
Returns a cell at random from the pattern.
Parameters:
- ip pattern for random cell retrieval
- rng (optional) A random number generating table, following the signature of math.random.
Returns:
-
a random cell in the pattern
- centroid (ip)
-
Compute the centroid of a pattern.
Returns the (arithmetic) mean position of all cells in an input pattern.
The centroid is rounded to the nearest integer-coordinate cell. Note this
does not neccesarily correspond to an /active/ cell in the input pattern.
If you need the closest active cell to the centroid, use pattern.medoid.
Parameters:
- ip input pattern
Returns:
-
the cell-coordinate centroid of
ip
- medoid (ip, measure)
-
Compute the medoid cell of a pattern.
Returns the cell with the minimum distance to all other cells in the
pattern, judged by any valid distance measure (default is Euclidean). The
medoid cell represents the centremost active cell of a pattern, for a given
distance metric.
Parameters:
- ip input pattern
- measure (optional) distance measure, default euclidean
Returns:
-
the medoid cell of
ip
for distance metricmeasure
Pattern manipulators
- shift (ip, sx, sy)
-
Generate a copy of a pattern shifted by a vector(x,y)
Parameters:
- ip pattern to be shifted
- sx amount to shift x-coordinates by
- sy amount to shift y-coordinates by
Returns:
-
New pattern consisting of ip shifted by (sx,sy)
- normalise (ip)
-
Copy a pattern, shifting its origin to (0,0).
Parameters:
- ip pattern to be normalised
Returns:
-
A new normalised pattern
- enlarge (ip, f)
-
Generate an enlarged version of a pattern.
This returns a new pattern in which each cell in an input pattern is
converted to a f*f cell block. The returned pattern is in such a way an
'enlarged' version of the input pattern, by a scale factor of 'f' in both x
and y.
Parameters:
- ip pattern to be enlarged
- f factor of enlargement
Returns:
-
enlarged pattern
- rotate (ip)
-
Rotate a pattern by 90° clockwise about the origin
Parameters:
- ip pattern to be rotated
Returns:
-
copy of
ip
which has been rotated by 90° - vreflect (ip)
-
Generate a copy of a pattern, mirroring it vertically.
Parameters:
- ip pattern for reflection
Returns:
-
copy of
ip
which has been is reflected vertically - hreflect (ip)
-
Generate a copy of a pattern, mirroring it horizontally.
Reflect a pattern horizontally
Parameters:
- ip pattern for reflection
Returns:
-
copy of
ip
which has been reflected horizontally - edge (ip, nbh)
-
Generate a pattern consisting of all cells on the edge of a provided pattern.
This returns a new pattern consisting of the inactive neighbours of an input
pattern, for a given definition of neighbourhood. Therefore the edge
method is useful for either enlarging patterns along their surface, or
determining a border of a pattern that does not overlap with the pattern
itself.
Parameters:
- ip pattern for which the edges should be calculated
- nbh defines which neighbourhood to scan in to determine edges (default 8/moore)
Returns:
-
A pattern representing the edge (outer hull) of ip
- surface (ip, nbh)
-
Generate a pattern consisting of cells on the surface of a provided pattern.
This returns a new pattern consisting of all active cells in an input pattern
that neighbour inactive cells. It is therefore very simmilar to pattern.edge but
returns a pattern which completely overlaps with the input pattern. This is therefore
useful when shrinking a pattern by removing a cell from its surface, or determining
a border of a pattern which consists of cells that are present in the original pattern.
Parameters:
- ip pattern for which the surface should be calculated
- nbh defines which neighbourhood to scan in to determine the surface (default 8/moore)
Returns:
-
A pattern representing the surface (inner hull) of ip
- intersection (...)
-
Generate a pattern consisting of the overlapping intersection of existing patterns
Parameters:
- ... patterns for intersection calculation
Returns:
-
A pattern consisting of the overlapping cells of the input patterns
- sum (...)
-
Generate a pattern consisting of the sum of existing patterns
Parameters:
- ... patterns for summation
Returns:
-
A pattern consisting of the sum of the input patterns
Packing methods
- packtile (a, b)
-
Returns a cell where pattern
a
overlaps with patternb
. The returned point has no particular properties w.r.t ordering of possible solutions. Solutions are returned 'first-come-first-served'.Parameters:
- a
the pattern to be packed in
b`. - b ` the domain which we are searching for packing solutions.
Returns:
-
a cell in
b
wherea
can be placed,nil
if impossible. - a
- packtile_centre (a, b)
-
Center-weighted version of pattern.packtile.
Tries to fit pattern
a
as close as possible to patternb
's centre.Parameters:
- a
the pattern to be packed into pattern
b
. - b the domain which we are searching for packing solutions
Returns:
-
a cell in
b
wherea
can be placed, nil if no solution found. - a
the pattern to be packed into pattern
Test methods
- get_max_coordinate ()
-
Returns the maximum hashable coordinate.
Returns:
-
MAX_COORDINATE
- test_coordinate_map (x, y)
-
Test the coordinate transform between (x,y) and spatial hash.
Parameters:
- x test coordinate x
- y test coordinate y
Returns:
-
true if the spatial hash is functioning correctly, false if not