Package squidpony.squidmath
Class CoordPacker
java.lang.Object
squidpony.squidmath.CoordPacker
public class CoordPacker extends Object
Provides static methods to encode Coords as single primitive ints in various ways, hence the namesake, but also
provides advanced methods to encode 2D arrays of various sorts produced by SquidLib in extremely memory-efficient
representations, and decode those representations to various types of 2D array on-demand. IMPORTANT: you must call
NOTE: Internally, this class is atypically complex and low-level for SquidLib because it is attempting to attain some very challenging performance gains. You should not consider it idiomatic SquidLib code or start modifying it unless you have a good grasp of bitwise operations and the performance implications, particularly in regard to memory consumption, that higher-level and more convenient Java programming techniques have.
NOTE 2: This class fills a role that is very similar to
The pack() methods in this class take a 2D array with a clear division between cells in an "on" state and cells in an "off" state, and they produce a very tightly compressed short array that can be losslessly decompressed with the unpack() methods to a boolean 2D array that stores equivalent on/off data to the input. The packMulti() method in this class takes a double 2D array that has more than two states that may need to be encoded, such as an FOV map that stores light level as a value between 0.0 and 1.0 instead of just on or off, and an additional double array that defines what states should be distinguished in the result (for example, if the FOV can store values that differ by 0.1 for a FOV radius of 10, you could pass the array of 10 levels: 0.1, 0.2, 0.3, ... 0.9, 1.0). The value returned by packMulti() is a short[][], but with different array lengths for each sub-array (a jagged array); the length of the short[][] is the same as the length of the levels array, and each sub-array corresponds to a different level of FOV lighting or other gradation as defined in levels. This short[][] can be passed to the unpackMultiByte() method in this class to produce a byte 2D array where the original levels correspond to progressively greater bytes, with 0 used for cells that were less than the smallest value in levels, 1 for values that were only greater than the smallest value, and no others, in levels, then 2 for larger values, etc. until it places a byte with a value equal to the length of levels in the cells that are the highest. There is also the unpackMultiDouble() method in this class that takes the same short[][] unpackMultiByte() can take, but also takes a levels double array that should be the same as the one used to compress short[][]. It will return a double 2D array with any cells that were smaller than the smallest value in levels assigned 0.0, and any other cells will be assigned a double that corresponds to the highest value in levels that does not exceed the original double at that location in the unpacked data. To make this more clear, if you have 4 levels: [0.25, 0.5, 0.75, 1.0] and you packMulti() on an FOV with a large radius and sample values 0.1, 0.45, 0.8, 1.0, you will get a packed short[][] with 4 sub-arrays to match the 4 levels. If you then pass the short[][] and levels to unpackMultiDouble later, much of the same radius will be filled, but because the sample value 0.1 was less than the smallest value in levels, its cell will be given 0.0. What was originally 0.45 will be given the next-lower levels value, 0.25; 0.8 will be given 0.75, and 1.0 will remain 1.0.
This compression is meant to produce a short[] or short[][] that uses as little memory as possible for the specific case of compressing maps with these qualities:
This table shows the results for the average of 100 runs of pack() in a map with a "good size" and 100 runs in a map with a "bad size." Both the compression ratio vs. a double[][] that stores only whether a cell is on or off and a boolean[][] that stores the same information are provided.
In the best-case scenario of packing a 240x240 double array to a short array encoding two states, the result
uses less than 1/8000 the memory that the input uses. Writing to disk can store both input and output more
efficiently, but the method used here should ensure that even encoding the input FOV map as a flat sequence of
single bits and compressing the file should still be on par with the output of pack() due to optimization to
ensure nearby cells on a map are compressed together.
The technique used by this class is to walk along a Hilbert Curve, storing whether the walk is traveling through "on" or "off" cells, which can be determined by a comparison to a number or a boolean, then encoding alternate shorts into the short[] to be returned, with even-number indices (starting at 0) in the array corresponding to the number of contiguous cells walked through in the "off" state, and odd-number indices corresponding to the number of contiguous cells walked through in the "on" state. A user of this library does not need to understand the details and properties of this algorithm unless they want to generate maps that will compress more optimally. In short:
The details of the algorithm are not terribly complex once you understand the Hilbert Curve. The simplified version of the Hilbert Curve that SquidLib employs is essentially a path through a square grid (it must have side lengths that are powers of 2, and SquidLib always uses 256), starting in the corner cell (x=0,y=0), ending in the corner cell (x=0,y=255), and traversing every other cell on the grid along its path without ever traveling in a loop, crossing the path it walked, or moving in any direction but one cell up, down, left, or right. The shape of the path this takes has the useful property of keeping most groups of cells walked through with similar x and y at similar distances traveled from the start of the curve, and most groups of cells with very dissimilar x and y at very different distances traveled. Since FOV and several other things you might want to encode with CoordPacker tends to be clustered in small areas and occupy more complicated shapes than straight lines due to dungeon layout blocking sections of FOV, the simplest paths of a wide zigzag from side-to-side, or an outward-going-in spiral, have rather poor behavior when determining how much of an area they pass through contiguously. The contiguous area trait is important because of the next step: Run-Length Encoding.
Run-Length Encoding is much simpler to explain than the Hilbert Curve, especially without visual aids. In the version SquidLib uses, only on or off states need to be recorded, so the method used here is smaller and more efficient than most methods that need to store repeated characters in strings (and letters, numbers, and punctuation clearly have more than 2 states). The technique works like this:
Start in the "off" state, walk down the Hilbert Curve counting how many cells you walk through that are still "off," and when you encounter a cell that is "on," you write down how many cells were off, transition to the "on" state. Now keep walking the Hilbert Curve, but counting how many cells you walk through that are still "on." When you reach an "off" cell, write down how many were "on," then start walking and counting again, with your count starting at 0. Repeat until you reach the end of the Hilbert Curve, but if you reach the end while counting "off" cells, you don't need to write down that number (a shortcut allows many maps to stop sooner than the 65,536th element of the Curve).
There are some additional traits that relate to the edge of the map being treated as "off" even though no calculations are done for cells out of map bounds, and some optimizations that ensure that maps that are smaller than a half, a quarter, or an eighth of the 256x256 curve in both dimensions (and sometimes just one) only need to walk a portion of the Hilbert Curve and simply skip the rest without walking it.
The Hilbert Curve has not been definitively proven to be the best possible path to ensure 1D distance and 2D location are similar, but it has been extensively used for tasks that require similar locations for similar distances (in particular, it has become useful in supercomputing clusters for allocating related work to physically nearby machines), and since there hasn't been anything with better spatial properties discovered yet, this technique should remain useful for some time.
Created by Tommy Ettinger on 10/1/2015.
init()
before using this class if you do not already use a SquidLib class that does so. It is a good habit
to call init() in your main() method or primary game entry point if you use CoordPacker. Failure to call init() will
not result in exceptions, but will make results inaccurate.
There's a detailed introduction
on the SquidLib wiki,
which is probably the best way to learn the techniques possible with this class. Most methods in this aren't useful
on their own, but can be mixed and matched to get specific regions from a map, such as all floors not adjacent to a
wall, or all grass within 3 squares of deep or shallow water, with walls blocking the distance measurement. You can
also use packed data that this class produces as keys for RegionMap
to associate values with regions.
NOTE: Internally, this class is atypically complex and low-level for SquidLib because it is attempting to attain some very challenging performance gains. You should not consider it idiomatic SquidLib code or start modifying it unless you have a good grasp of bitwise operations and the performance implications, particularly in regard to memory consumption, that higher-level and more convenient Java programming techniques have.
NOTE 2: This class fills a role that is very similar to
GreasedRegion
, and there are times when code will do
better using CoordPacker than GreasedRegion and vice versa. GreasedRegion uses objects and tries to change them
in-place whenever possible instead of allocating new data; CoordPacker uses short[] values that it never changes
in-place and frequently allocates new short[] values to represent data. GreasedRegion stores the full map without any
compression beyond "one bit per cell" and always needs to store all cells on the map (sometimes slightly more);
CoordPacker can compress some data to significantly less than one bit per cell, and doesn't care about the maximum
bounds of the map as long as it fits inside a 256x256 square. GreasedRegion is significantly faster than CoordPacker
when performing any operations that move, shrink, or expand an area, such as expand(short[], int, int, int)
,
retract(short[], int, int, int)
, and translate(short[], int, int, int, int)
. CoordPacker usually
(not always) uses somewhat less memory than GreasedRegion, though both use very little unless the maps are very
large or very numerous. Both can do essentially the same things, except that GreasedRegion has no equivalent to the
packMulti(byte[][], int)
and other Multi kinds of method, no radiate(short[], short[], int)
, and no
reachable(short[], short[], Reach)
, while CoordPacker has no equivalent to
GreasedRegion.expandSeriesToLimit()
and other ToLimit kinds of method, no
GreasedRegion.toggle(int, int)
, no GreasedRegion.deteriorate(RandomnessSource, int)
, no
GreasedRegion.insert(int, int, GreasedRegion)
(though CoordPacker can generally use
unionPacked(short[], short[])
for that), and several other methods don't have equivalents. In general, you
will probably find GreasedRegion more intuitive because it involves working with objects instead of a short[] that is
treated like a particular kind of data, and the methods are also somewhat more clearly-named. GreasedRegion also
implements Collection of Coord, while the short[] data can't implement anything. A way around this for CoordPacker is
the CoordPackerZone
class; both that and GreasedRegion implement the
Zone
interface, which ensures a way to get a List of Coord from the Zone.
The pack() methods in this class take a 2D array with a clear division between cells in an "on" state and cells in an "off" state, and they produce a very tightly compressed short array that can be losslessly decompressed with the unpack() methods to a boolean 2D array that stores equivalent on/off data to the input. The packMulti() method in this class takes a double 2D array that has more than two states that may need to be encoded, such as an FOV map that stores light level as a value between 0.0 and 1.0 instead of just on or off, and an additional double array that defines what states should be distinguished in the result (for example, if the FOV can store values that differ by 0.1 for a FOV radius of 10, you could pass the array of 10 levels: 0.1, 0.2, 0.3, ... 0.9, 1.0). The value returned by packMulti() is a short[][], but with different array lengths for each sub-array (a jagged array); the length of the short[][] is the same as the length of the levels array, and each sub-array corresponds to a different level of FOV lighting or other gradation as defined in levels. This short[][] can be passed to the unpackMultiByte() method in this class to produce a byte 2D array where the original levels correspond to progressively greater bytes, with 0 used for cells that were less than the smallest value in levels, 1 for values that were only greater than the smallest value, and no others, in levels, then 2 for larger values, etc. until it places a byte with a value equal to the length of levels in the cells that are the highest. There is also the unpackMultiDouble() method in this class that takes the same short[][] unpackMultiByte() can take, but also takes a levels double array that should be the same as the one used to compress short[][]. It will return a double 2D array with any cells that were smaller than the smallest value in levels assigned 0.0, and any other cells will be assigned a double that corresponds to the highest value in levels that does not exceed the original double at that location in the unpacked data. To make this more clear, if you have 4 levels: [0.25, 0.5, 0.75, 1.0] and you packMulti() on an FOV with a large radius and sample values 0.1, 0.45, 0.8, 1.0, you will get a packed short[][] with 4 sub-arrays to match the 4 levels. If you then pass the short[][] and levels to unpackMultiDouble later, much of the same radius will be filled, but because the sample value 0.1 was less than the smallest value in levels, its cell will be given 0.0. What was originally 0.45 will be given the next-lower levels value, 0.25; 0.8 will be given 0.75, and 1.0 will remain 1.0.
This compression is meant to produce a short[] or short[][] that uses as little memory as possible for the specific case of compressing maps with these qualities:
- Maps are not especially large for a grid-based game; the maximum size is 256x256 cells.
- The vast majority of that 256x256 space is either unused or filled with cells no greater than 0.
- The cells that are greater than 0 are mostly near each other, though separate areas are possible.
DungeonGenerator
that should be typical of
roguelike maps and a diamond-shaped FOV with radius 8, compression of the short[] returned by pack() vs.
the original double[][] (which wastefully represents 2 states with 8 bytes) yields average memory usage ratios
between (with relatively optimal parameters) 0.0001237905030818498 in one of the best cases, and (with some very
poor parameters for the dungeon, but still using a realistic FOV map) 0.003135985198889917 in one of the worst.
This table shows the results for the average of 100 runs of pack() in a map with a "good size" and 100 runs in a map with a "bad size." Both the compression ratio vs. a double[][] that stores only whether a cell is on or off and a boolean[][] that stores the same information are provided.
Bytes of RAM used, double 2D array | Bytes of RAM used, boolean 2D array | Average Bytes of RAM used, short 1D array (packed) | Compression ratio, packed vs. doubles | Compression ratio, packed vs. booleans | |
---|---|---|---|---|---|
240x240 dungeon map (good size) | 464656 | 61456 | 57.52 | 0.0001237905030818498 | 0.000935954178599323 |
30x70 dungeon map (bad size) | 17296 | 2656 | 54.24 | 0.003135985198889917 | 0.020421686746987953 |
The technique used by this class is to walk along a Hilbert Curve, storing whether the walk is traveling through "on" or "off" cells, which can be determined by a comparison to a number or a boolean, then encoding alternate shorts into the short[] to be returned, with even-number indices (starting at 0) in the array corresponding to the number of contiguous cells walked through in the "off" state, and odd-number indices corresponding to the number of contiguous cells walked through in the "on" state. A user of this library does not need to understand the details and properties of this algorithm unless they want to generate maps that will compress more optimally. In short:
- Smaller maps tend to be processed faster by pack(), since the nature of a Hilbert Curve means a map that fits in one half the width and one half the height of the curve only needs to walk one quarter of the Curve to get all the needed information.
- Smaller maps also compress less optimally ratio-wise than larger maps with the same area of "on" cells. The compression ratio approaches its best when using very large maps, such as 240x240, and encoding just a few cells on that map (such as for a small FOV radius or a cramped room). A map that is entirely "off" uses only 16 bytes of RAM (the minimum for any array on the JVM).
- Unusually shaped maps can cause compression problems by forcing adjacent cells to sometimes require walking more cells than needed to get to an adjacent cell. For example, a map greater than 64 cells tall, but less than 33 cells wide, has properties that require walking through a large empty area to get to sometimes only a few cells that are "on" before it walks back through empty space. Similarly, a map that is greater than 128 cells tall but is otherwise narrow has the same property of requiring walking through empty space, but also requires the entire Curve to be walked even if the map's width is only a tiny fraction of the Curve's 256 cells.
The details of the algorithm are not terribly complex once you understand the Hilbert Curve. The simplified version of the Hilbert Curve that SquidLib employs is essentially a path through a square grid (it must have side lengths that are powers of 2, and SquidLib always uses 256), starting in the corner cell (x=0,y=0), ending in the corner cell (x=0,y=255), and traversing every other cell on the grid along its path without ever traveling in a loop, crossing the path it walked, or moving in any direction but one cell up, down, left, or right. The shape of the path this takes has the useful property of keeping most groups of cells walked through with similar x and y at similar distances traveled from the start of the curve, and most groups of cells with very dissimilar x and y at very different distances traveled. Since FOV and several other things you might want to encode with CoordPacker tends to be clustered in small areas and occupy more complicated shapes than straight lines due to dungeon layout blocking sections of FOV, the simplest paths of a wide zigzag from side-to-side, or an outward-going-in spiral, have rather poor behavior when determining how much of an area they pass through contiguously. The contiguous area trait is important because of the next step: Run-Length Encoding.
Run-Length Encoding is much simpler to explain than the Hilbert Curve, especially without visual aids. In the version SquidLib uses, only on or off states need to be recorded, so the method used here is smaller and more efficient than most methods that need to store repeated characters in strings (and letters, numbers, and punctuation clearly have more than 2 states). The technique works like this:
Start in the "off" state, walk down the Hilbert Curve counting how many cells you walk through that are still "off," and when you encounter a cell that is "on," you write down how many cells were off, transition to the "on" state. Now keep walking the Hilbert Curve, but counting how many cells you walk through that are still "on." When you reach an "off" cell, write down how many were "on," then start walking and counting again, with your count starting at 0. Repeat until you reach the end of the Hilbert Curve, but if you reach the end while counting "off" cells, you don't need to write down that number (a shortcut allows many maps to stop sooner than the 65,536th element of the Curve).
There are some additional traits that relate to the edge of the map being treated as "off" even though no calculations are done for cells out of map bounds, and some optimizations that ensure that maps that are smaller than a half, a quarter, or an eighth of the 256x256 curve in both dimensions (and sometimes just one) only need to walk a portion of the Hilbert Curve and simply skip the rest without walking it.
The Hilbert Curve has not been definitively proven to be the best possible path to ensure 1D distance and 2D location are similar, but it has been extensively used for tasks that require similar locations for similar distances (in particular, it has become useful in supercomputing clusters for allocating related work to physically nearby machines), and since there hasn't been anything with better spatial properties discovered yet, this technique should remain useful for some time.
Created by Tommy Ettinger on 10/1/2015.
- Author:
- Tommy Ettinger
-
Field Summary
Fields Modifier and Type Field Description static short[]
ALL_ON
static short[]
ALL_WALL
static int
DEPTH
static short[]
hilbert3Distances
static short[]
hilbert3X
static short[]
hilbert3Y
static short[]
hilbert3Z
static short[]
hilbertDistances
static short[]
hilbertX
static short[]
hilbertY
static short[]
mooreDistances
static short[]
mooreX
static short[]
mooreY
-
Method Summary
Modifier and Type Method Description static Coord[]
allPacked(short[] packed)
Gets all positions that are "on" in the given packed array, without unpacking it, and returns them as a Coord[].static short[]
allPackedHilbert(short[] packed)
Gets all positions that are "on" in the given packed array, without unpacking it, and returns them as an array of Hilbert Curve indices.static Coord[]
apartPacked(short[] packed, int minDistance)
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as a Coord[].static Coord[]
apartPacked(short[] packed, int minDistance, boolean eightWay)
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as a Coord[].static short[]
apartPackedHilbert(short[] packed, int minDistance)
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as an array of Hilbert Curve indices.static short[]
apartPackedHilbert(short[] packed, int minDistance, boolean eightWay)
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as an array of Hilbert Curve indices.static Coord[]
bounds(short[] packed)
Finds the minimum bounding rectangle for a packed array without unpacking it.static short[]
circle(Coord center, int radius, int width, int height)
Given a center and radius for a circle, plus the width and height for the map boundaries, returns the packed data that encodes the circle.static int
coordToHilbert(Coord pt)
Takes a position as a Coord called pt and returns the length to travel along the 256x256 Hilbert curve to reach that position.static int
coordToMoore(Coord pt)
Takes a position as a Coord called pt and returns the length to travel along the 16x16 Moore curve to reach that position.static int
count(short[] packed)
Counts the number of "on" cells encoded in a packed array without unpacking it.static int
count(short[] packed, boolean wanted)
Counts the number of cells encoding a boolean equal to wanted in a packed array without unpacking it.static int
covered(short[] packed)
Finds how many cells are encoded in a packed array (both on and off) without unpacking it.static short[]
decodeASCII(String text)
Given a String specifically produced by CoordPacker.encodeASCII(), this will produce a packed data array.static short[]
decodeBraille(String text)
Given a String specifically produced by CoordPacker.encodeBraille(), this will produce a packed data array.static short[]
differencePacked(short[] left, short[] right)
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in left but "off" in right, and encodes "off" for cells that were "on" in right or "off" in left.static String
encodeASCII(short[] packed)
Encodes a short array of packed data as a (larger, more memory-hungry) ASCII string, which can be decoded using CoordPacker.decodeASCII() .static String
encodeBraille(short[] packed)
Encodes a short array of packed data as a (larger, slightly more memory-hungry) Unicode string using only Braille characters, which can be decoded using CoordPacker.decodeBraille().static short[]
expand(short[] packed, int expansion, int width, int height)
Expand each "on" position in packed to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge.static short[]
expand(short[] packed, int expansion, int width, int height, boolean eightWay)
Expand each "on" position in packed to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge.static OrderedSet<short[]>
findManyPacked(int x, int y, short[]... packed)
Quickly determines if an x,y position is true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.static OrderedSet<short[]>
findManyPacked(int x, int y, Collection<short[]> packed)
Quickly determines if an x,y position is true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.static ArrayList<short[]>
findManyPackedHilbert(short hilbert, short[]... packed)
Quickly determines if a Hilbert Curve index corresponds to true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.static short[]
flood(short[] bounds, short[] start, int expansion)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a Manhattan (diamond) radius equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static short[]
flood(short[] bounds, short[] start, int expansion, boolean eightWay)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius (if eightWay is true, it uses Chebyshev distance; if it is false, it uses Manhattan distance) equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static Coord[]
fractionPacked(short[] packed, int fraction)
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores one of those cells as a Coord, and returns the accumulated portion of positions as a Coord[].static short[]
fractionPackedHilbert(short[] packed, int fraction)
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores one of those cells as a Coord, and returns the accumulated portion of positions as an array of Hilbert Curve indices.static short[]
fringe(short[] packed, int expansion, int width, int height)
Finds the area around the cells encoded in packed, without including those cells.static short[]
fringe(short[] packed, int expansion, int width, int height, boolean eightWay)
Finds the area around the cells encoded in packed, without including those cells.static short[]
fringe(short[] packed, int expansion, int width, int height, boolean eightWay, boolean drop)
Finds the area around the cells encoded in packed, without including those cells.static short[][]
fringes(short[] packed, int expansions, int width, int height)
Finds the concentric areas around the cells encoded in packed, without including those cells.static short[][]
fringes(short[] packed, int expansions, int width, int height, boolean eightWay)
Finds the concentric areas around the cells encoded in packed, without including those cells.static double[]
generateLightLevels(int totalLevels)
Given a number of total levels to consider separate in a double[][] such as an FOV result, this produces a levels array that can be passed to unpackMultiDouble() to ensure that the minimum double returned for an "on" cell is 1.0 / totalLevels, and every progressively tighter level in the short[][] being unpacked will be close to a multiple of that minimum double value.static double[]
generatePackingLevels(int totalLevels)
Given a number of total levels to consider separate in a double[][] such as an FOV result, this produces a levels array that can be passed to packMulti() to ensure that you have the requested number of separate levels in the multi-packed result.static int
getXMoore3D(int index, int n)
Gets the x coordinate for a given index into the 16x16x(8*n) Moore curve.static int
getYMoore3D(int index, int n)
Gets the y coordinate for a given index into the 16x16x(8*n) Moore curve.static int
getZMoore3D(int index, int n)
Gets the z coordinate for a given index into the 16x16x(8*n) Moore curve.static int
grayDecode(int n)
Decode a number from a Gray code n; Gray codes have a relation to the Hilbert curve and may be useful.static int
grayEncode(int n)
Encode a number n as a Gray code; Gray codes have a relation to the Hilbert curve and may be useful.static Coord
hilbertToCoord(int hilbert)
Takes a distance to travel along the 256x256 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve.static int
hilbertToMorton(int hilbert)
Takes a distance to travel along the 256x256 Hilbert curve and returns a Morton code representing the position in 2D space that corresponds to that point on the Hilbert Curve; the Morton code will have interleaved x and y bits and x in the least significant bit.static void
init()
static short[]
insertPacked(short[] original, int x, int y)
Given one packed short array, original, and a position as x,y numbers, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by x and y, and encodes "off" for cells that were "off" in original and are not the cell x and y refer to.static short[]
insertPacked(short[] original, short hilbert)
Given one packed short array, original, and a Hilbert Curve index, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by hilbert, and encodes "off" for cells that were "off" in original and are not the cell hilbert refers to.static short[]
insertSeveralPacked(short[] original, int... hilbert)
Given one packed short array, original, and a number of Hilbert Curve indices, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of hilbert, and encodes "off" for cells that were "off" in original and are not in any cell hilbert refers to.static short[]
insertSeveralPacked(short[] original, Collection<Coord> points)
Given one packed short array, original, and a Collection of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of points, and encodes "off" for cells that were "off" in original and are not in any cell points refers to.static short[]
insertSeveralPacked(short[] original, Coord... points)
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of points, and encodes "off" for cells that were "off" in original and are not in any cell points refers to.static short[]
intersectPacked(short[] left, short[] right)
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in both left and in right, and encodes "off" for cells that were off in either array.static boolean
intersects(short[] left, short[] right)
Given two packed short arrays, left and right, this returns true if they encode any overlapping area (their areas intersect), or false if they do not overlap at all (they don't intersect).static boolean
isEmpty(short[] packed)
Checks if no cells are encoded as "on" in packed.static char[][]
mask(char[][] map, short[] packed, char filler)
Given a 2D char array for a map, a piece of packed data defining a region to use from that map, and a filler char, produces a 2D char array where all positions that are "off" in packed are filled with filler, and the rest are the same as in map.static Coord
mooreToCoord(int moore)
Takes a distance to travel along the 16x16 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve.static int
mortonBitDecode3D(int morton)
static Coord
mortonDecode(int morton)
Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position.static Coord3D
mortonDecode3D(int morton)
static int
mortonEncode(int index1, int index2)
Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit.static int
mortonEncode3D(int index1, int index2, int index3)
static int
mortonToHilbert(int morton)
Takes a position as a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the length to travel along the 256x256 Hilbert Curve to reach that position.static short[]
negatePacked(short[] original)
Given one packed short array, this produces a packed short array that is the exact opposite of the one passed in, that is, every "on" cell becomes "off" and every "off" cell becomes "on", including cells that were "off" because they were beyond the boundaries of the original 2D array passed to pack() or a similar method.static Coord
nth(short[] packed, int n)
Gets the nth position that is "on" in the given packed array, without unpacking it, and returns it as a Coord.static short[]
pack(boolean[][] map)
Compresses a boolean[][], returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(byte[][] map)
Compresses a byte[][] (typically one generated by an FOV-like method) that only stores two relevant states (one of which should be 0 or less, the other greater than 0), returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(char[][] map, char yes)
Compresses a char[][] (typically one generated by a map generating method) so only the cells that equal the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(char[][] map, char... yes)
Compresses a char[][] (typically one generated by a map generating method) so only the cells that are contained in the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(double[][] map)
Compresses a double[][] (typically one generated byFOV
) that only stores two relevant states (one of which should be 0 or less, the other greater than 0), returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(double[][] map, double threshold)
Compresses a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states (one of which should be equal to or less than threshold, the other greater than threshold), returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(double[][] map, double lowerBound, double upperBound)
Compresses a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states (a state for values between lowerBound (inclusive) and upperBound (exclusive), and another state for anything else), returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(int[][] map, int yes)
Compresses a int[][] (typically one generated by MixedGenerator.getEnvironment()) so only the cells that equal the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation.static short[]
pack(int[][] map, int... yes)
Compresses a int[][] (typically one generated by MixedGenerator.getEnvironment()) so only the cells that are contained in the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation.static short[][]
packMulti(byte[][] map, int levelCount)
Compresses a byte[][] that stores any number of states, and an int no more than 63, returning a short[][] as described in theCoordPacker
class documentation.static short[][]
packMulti(double[][] map, double[] levels)
Compresses a double[][] (typically one generated byFOV
) that stores any number of states and a double[] storing up to 63 states, ordered from lowest to highest, returning a short[][] as described in theCoordPacker
class documentation.static short[]
packOne(int hilbert)
Returns a new packed short[] containing the Hilbert distance hilbert as "on", and all other cells "off".static short[]
packOne(int x, int y)
Returns a new packed short[] containing the given x,y cell as "on", and all other cells "off".static short[]
packOne(Coord point)
Returns a new packed short[] containing the Coord point as "on", and all other cells "off".static short[]
packSeveral(int... hilbert)
Returns a new packed short[] containing the Hilbert distances in hilbert as "on" cells, and all other cells "off"static short[]
packSeveral(Collection<Coord> points)
Returns a new packed short[] containing the Coords in points as "on" cells, and all other cells "off"static short[]
packSeveral(Coord... points)
Returns a new packed short[] containing the Coords in points as "on" cells, and all other cells "off"static int
posToHilbert(int x, int y)
Takes an x, y position and returns the length to travel along the 256x256 Hilbert curve to reach that position.static int
posToHilbert3D(int x, int y, int z)
Takes an x, y, z position and returns the length to travel along the 8x8x8 Hilbert curve to reach that position.static int
posToMoore(int x, int y)
Takes an x, y position and returns the length to travel along the 16x16 Moore curve to reach that position.static void
printCompressedData(short[] packed)
static void
printPacked(short[] packed, int width, int height)
Quick utility method for printing packed data as a grid of 1 (on) and/or 0 (off).static boolean
queryPacked(short[] packed, int x, int y)
Quickly determines if an x,y position is true or false in the given packed array, without unpacking it.static boolean
queryPackedHilbert(short[] packed, short hilbert)
Quickly determines if a Hilbert Curve index corresponds to true or false in the given packed array, without unpacking it.static short[]
radiate(short[] bounds, short[] start, int expansion)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a Manhattan (diamond) radius equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static short[]
radiate(short[] bounds, short[] start, int expansion, boolean eightWay)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius, with a square shape if eightWay is true or a diamond otherwise, equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static short[]
radiate(short[] bounds, short[] start, int expansion, Radius metric)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius, with a shape determined by metric, equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static ArrayList<Coord>
randomPortion(short[] packed, int size, IRNG rng)
Gets a fixed number of randomly chosen positions that are "on" in the given packed array, without unpacking it, and returns a List of Coord with a count equal to size (or less if there aren't enough "on" cells).static Coord[]
randomSample(short[] packed, double fraction, IRNG rng)
Gets a random subset of positions that are "on" in the given packed array, without unpacking it, and returns them as a Coord[].static Coord[]
randomSeparated(short[] packed, int separation, IRNG rng)
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores a random one of those cells as a Coord, and returns the accumulated random portion of positions as a Coord[].static short[]
reachable(short[] bounds, short[] start, Reach reach)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and a Reach object that determines targeting constraints, gets all cells contained within bounds that can be targeted from a cell in start using the rules defined by reach.static short[]
rectangle(int width, int height)
Given a width and height, returns a packed array that encodes "on" for the rectangle from (0,0) to (width - 1, height - 1).static short[]
rectangle(int x, int y, int width, int height)
Given x, y, width and height, returns a packed array that encodes "on" for the rectangle from (x,y) to (width + x - 1, height + y - 1).static short[]
rectangleHilbert(int x, int y, int width, int height)
Given x, y, width and height, returns an array of all Hilbert distance within the rectangle from (x,y) to (width + x - 1, height + y - 1).static boolean
regionsContain(short[] checking, short[]... packed)
Quickly determines if a region is contained in one of the given packed arrays, without unpacking them, and returns true if the region checking has some overlap with any of the packed arrays, or false otherwise.static boolean
regionsContain(short[] checking, Collection<short[]> packed)
Quickly determines if a region is contained in one of the given packed arrays, without unpacking them, and returns true if the region checking has some overlap with any of the packed arrays, or false otherwise.static short[]
removeIsolated(short[] packed)
static short[]
removePacked(short[] original, int x, int y)
Given one packed short array, original, and a position as x,y numbers, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was the position referred to by x and y, and encodes "off" for cells that were "off" in original or are the cell x and y refer to.static short[]
removePacked(short[] original, short hilbert)
Given one packed short array, original, and a Hilbert Curve index, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was the position referred to by hilbert, and encodes "off" for cells that were "off" in original or are the cell hilbert refers to.static short[]
removeSeveralPacked(short[] original, int... hilbert)
Given one packed short array, original, and a number of Hilbert Curve indices, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by hilbert, and encodes "off" for cells that were "off" in original and are a cell hilbert refers to.static short[]
removeSeveralPacked(short[] original, Collection<Coord> points)
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by an element in points, and encodes "off" for cells that were "off" in original and are a cell points refers to.static short[]
removeSeveralPacked(short[] original, Coord... points)
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by an element in points, and encodes "off" for cells that were "off" in original and are a cell points refers to.static short[]
retract(short[] packed, int retraction, int width, int height)
Finds the area made by removing the "on" positions in packed that are within the specified retraction distance of an "off" position or the edge of the map.static short[]
retract(short[] packed, int retraction, int width, int height, boolean eightWay)
Finds the area made by removing the "on" positions in packed that are within the specified retraction distance of an "off" position or the edge of the map.static Coord
singleRandom(short[] packed, IRNG rng)
Gets a single randomly chosen position that is "on" in the given packed array, without unpacking it, and returns it as a Coord or returns null of the array is empty.static short[]
spill(short[] bounds, short[] start, int volume, IRNG rng)
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, an IRNG, and a volume in cells, expands a random cell in start in a random Manhattan (diamond) direction equal, then continues to expand from random cells in start or the expanded area until it has filled volume cells, limiting any expansion to within bounds and returning the final expanded (limited) packed data.static ArrayList<short[]>
split(short[] packed)
Given a packed data array that encodes multiple unconnected "on" areas, this finds each isolated area (areas that are only adjacent diagonally are considered separate from each other) and returns it as an element in an ArrayList of short[], with one short[] array per isolated area.static int[][]
sumMany(int width, int height, short[]... many)
Takes multiple pieces of packed data as short[], encoded by pack() or another similar method of this class, and generates a 2D int array with the specified width and height and a starting value of 0 for all elements, then where every occurrence of a cell as "on" in a piece of packed data increments the cell's value in the returned array.static short[]
surface(short[] packed, int depth, int width, int height)
Finds the area consisting of the "on" positions in packed that are within the specified depth distance of an "off" position or the edge of the map.static short[]
surface(short[] packed, int depth, int width, int height, boolean eightWay)
Finds the area consisting of the "on" positions in packed that are within the specified depth distance of an "off" position or the edge of the map.static short[][]
surfaces(short[] packed, int depth, int width, int height)
Finds the concentric, progressively-smaller surfaces of packed as if packed was shrinking with each iteration.static short[][]
surfaces(short[] packed, int depth, int width, int height, boolean eightWay)
Finds the concentric, progressively-smaller surfaces of packed as if packed was shrinking with each iteration.static short[]
translate(short[] packed, int xMove, int yMove, int width, int height)
Move all "on" positions in packed by the number of cells given in xMove and yMove, unless the move would take them further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge (moving any shape by an xMove greater than width or yMove greater than height will move all "on" cells to that edge, in a 1-cell thick line).static short[]
unionPacked(short[] left, short[] right)
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in either left or in right, and only encodes "off" for cells that were off in both.static boolean[][]
unpack(short[] packed, int width, int height)
Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation.static char[][]
unpackChar(short[] packed, char t, char f)
Given a piece of packed data defining a region to use from that map, a char to use for "on" cells and a char to use for "off" cells, produces a 2D char array where all positions that are "off" in packed are filled with the char passed as f, and the cells that are "on" are filled with the char passed as t.static char[][]
unpackChar(short[] packed, int width, int height, char t, char f)
Given a piece of packed data defining a region to use from that map, a desired width and height, a char to use for "on" cells and a char to use for "off" cells, produces a 2D char array where all positions that are "off" in packed are filled with the char passed as f, and the cells that are "on" are filled with the char passed as t.static double[][]
unpackDouble(short[] packed, int width, int height)
Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation.static double[][]
unpackDoubleConical(short[] packed, int width, int height, int centerX, int centerY, double angle, double span)
Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation.static GreasedRegion
unpackGreasedRegion(short[] packed, int width, int height)
Utility method that constructs a GreasedRegion (a faster but more-memory-hungry way to encode regions) from a short array of packed data.static GreasedRegion
unpackIntoGreasedRegion(short[] packed, GreasedRegion target)
Utility method that fills an existing GreasedRegiontarget
with any "on" cells in the packed short arraypacked
.static GreasedRegion
unpackIntoGreasedRegion(short[] packed, GreasedRegion target, int offsetX, int offsetY)
Utility method that fills an existing GreasedRegiontarget
with any "on" cells in the packed short arraypacked
, inserting cells from packed at an offset when they go into target.static byte[][]
unpackMultiByte(short[][] packed, int width, int height)
Decompresses a short[][] returned by packMulti() and produces a simple 2D array where the values are bytes corresponding to 1 + the highest index into levels (that is, the original levels parameter passed to packMulti) matched by a cell, or 0 if the cell didn't match any levels during compression, as described in theCoordPacker
class documentation.static double[][]
unpackMultiDouble(short[][] packed, int width, int height, double[] levels)
Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, as described in theCoordPacker
class documentation.static double[][]
unpackMultiDoublePartial(short[][] packed, int width, int height, double[] levels, int limit)
Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, but only using the innermost indices up to limit, as described in theCoordPacker
class documentation.static double[][]
unpackMultiDoublePartialConical(short[][] packed, int width, int height, double[] levels, int limit, int centerX, int centerY, double angle, double span)
Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, but only using the innermost indices up to limit, as described in theCoordPacker
class documentation.static short[]
xorPacked(short[] left, short[] right)
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" only in left or only in right, but not a cell that was "off" in both or "on" in both.static Coord
zDecode(short morton)
Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position.static short
zEncode(short index1, short index2)
Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit.
-
Field Details
-
Method Details
-
init
-
pack
Compresses a double[][] (typically one generated byFOV
) that only stores two relevant states (one of which should be 0 or less, the other greater than 0), returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the relevant states and their positions as a boolean[][] (with false meaning 0 or less and true being any double greater than 0). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps. To avoid floating-point number comparison issues, this actually needs doubles to be greater than 0.0001, which should never cause incorrect behavior with FOV's double[][] maps.
To store more than two states, you should use packMulti().- Parameters:
map
- a double[][] that probably was returned by FOV. If you obtained a double[][] from DijkstraMap, it will not meaningfully compress with this method.- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states (one of which should be equal to or less than threshold, the other greater than threshold), returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the relevant states and their positions as a boolean[][] (with true meaning threshold or less and false being any double greater than threshold). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but here is also useful for compressing physical maps and gradient maps from DijkstraMap.
To store more than two states, you should use packMulti().- Parameters:
map
- a double[][] that probably relates in some way to DijkstraMap.threshold
- upper inclusive; any double greater than this will be off, any equal or less will be on- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states (a state for values between lowerBound (inclusive) and upperBound (exclusive), and another state for anything else), returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the relevant states and their positions as a boolean[][] (with true meaning between the bounds and false being anything outside them). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but here is also useful for compressing physical maps and gradient maps from DijkstraMap.
To store more than two states, you should use packMulti().- Parameters:
map
- a double[][] that probably relates in some way to DijkstraMap.lowerBound
- lower inclusive; any double lower than this will be off, any equal to or greater than this, but less than upper, will be onupperBound
- upper exclusive; any double greater than this will be off, any doubles both less than this and equal to or greater than lower will be on- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a byte[][] (typically one generated by an FOV-like method) that only stores two relevant states (one of which should be 0 or less, the other greater than 0), returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the relevant states and their positions as a boolean[][] (with false meaning 0 or less and true being any byte greater than 0). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps.
To store more than two states, you should use packMulti().- Parameters:
map
- a byte[][] that probably was returned by an FOV-like method.- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a boolean[][], returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the relevant states and their positions as a boolean[][] As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps.- Parameters:
map
- a boolean[][] that should ideally be mostly false.- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a char[][] (typically one generated by a map generating method) so only the cells that equal the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the positions of chars that equal the parameter yes as a boolean[][] (with false meaning not equal and true equal to yes). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but this will typically not be used for FOV (more typical uses are for walls, floors, and so on). This can still be useful for certain kinds of processing that can be done more efficiently on packed data than on 2D arrays, like unions, intersections, and random elements or subsets.- Parameters:
map
- a char[][] that may contain some area of cells that you want stored as packed datayes
- the char to encode as "on" in the result; all others are encoded as "off"- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a char[][] (typically one generated by a map generating method) so only the cells that are contained in the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the positions of chars that equal the parameter yes as a boolean[][] (with false meaning not equal and true equal to yes). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but this will typically not be used for FOV (more typical uses are for walls, floors, and so on). This can still be useful for certain kinds of processing that can be done more efficiently on packed data than on 2D arrays, like unions, intersections, and random elements or subsets.- Parameters:
map
- a char[][] that may contain some area of cells that you want stored as packed datayes
- the vararg or array of chars to encode as "on" in the result; all others are encoded as "off"- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a int[][] (typically one generated by MixedGenerator.getEnvironment()) so only the cells that equal the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the positions of ints that equal the parameter yes as a boolean[][] (with false meaning not equal and true equal to yes). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but this will typically not be used for FOV (more typical uses are for walls, floors, and so on). This can still be useful for certain kinds of processing that can be done more efficiently on packed data than on 2D arrays, like unions, intersections, and random elements or subsets.- Parameters:
map
- a int[][] that may contain some area of cells that you want stored as packed datayes
- the int to encode as "on" in the result; all others are encoded as "off"- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
pack
Compresses a int[][] (typically one generated by MixedGenerator.getEnvironment()) so only the cells that are contained in the yes parameter will be encoded as "on", returning a short[] as described in theCoordPacker
class documentation. This short[] can be passed to CoordPacker.unpack() to restore the positions of ints that equal the parameter yes as a boolean[][] (with false meaning not equal and true equal to yes). As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps, but this will typically not be used for FOV (more typical uses are for walls, floors, and so on). This can still be useful for certain kinds of processing that can be done more efficiently on packed data than on 2D arrays, like unions, intersections, and random elements or subsets.- Parameters:
map
- a int[][] that may contain some area of cells that you want stored as packed datayes
- the vararg or array of ints to encode as "on" in the result; all others are encoded as "off"- Returns:
- a packed short[] that should, in most circumstances, be passed to unpack() when it needs to be used.
-
generatePackingLevels
Given a number of total levels to consider separate in a double[][] such as an FOV result, this produces a levels array that can be passed to packMulti() to ensure that you have the requested number of separate levels in the multi-packed result. For example, if you pass 6 to this method, it will return a length-6 double array, and if you pass that as the levels parameter to packMulti(), then that method will return a length-6 array of short arrays that each encode a region that met a different minimum value in the originally packed double[][]. The behavior of this method causes any doubles that are closer to 1.0 / totalLevels than they are to 0.0 to be packed as "on" in at least one of packMulti()'s resultant sub-arrays. This allows Radius.CIRCLE or similar FOV that produces cells with values that aren't evenly distributed between 0.0 and 1.0 to be used without causing an explosion in the number of required levels.
This method should not be used to generate levels for unpacking; it is only intended for packing. Use the similar method generateLightLevels() to generate a levels array that is suitable for unpacking FOV.- Parameters:
totalLevels
- the number of separate levels to group doubles into- Returns:
- a double[] suitable as a levels parameter for packMulti()
-
generateLightLevels
Given a number of total levels to consider separate in a double[][] such as an FOV result, this produces a levels array that can be passed to unpackMultiDouble() to ensure that the minimum double returned for an "on" cell is 1.0 / totalLevels, and every progressively tighter level in the short[][] being unpacked will be close to a multiple of that minimum double value. This only applies to "on" cells; any cells that did not meet a minimum value when packed will still be 0.0. For example, if you pass 6 to this method, it will return a length-6 double array, and if you pass that as the levels parameter to unpackMultiDouble(), then that method will return a double[][] with no more than totalLevels + 1 used values, ranging from 0.0 to 1.0 with evenly spaced values, all multiples of 1.0 / totalLevels, in between.
This method should not be used to generate levels for packing; it is only intended for unpacking. Use the similar method generatePackingLevels() to generate a levels array that is suitable for packing double[][] values.- Parameters:
totalLevels
- the number of separate levels to assign doubles; this MUST match the size of the levels parameter used to pack a double[][] with packMulti() if this is used to unpack that data- Returns:
- a double[] suitable as a levels parameter for unpackMultiDouble()
-
packMulti
Compresses a double[][] (typically one generated byFOV
) that stores any number of states and a double[] storing up to 63 states, ordered from lowest to highest, returning a short[][] as described in theCoordPacker
class documentation. This short[][] can be passed to CoordPacker.unpackMultiDouble() to restore the state at a position to the nearest state in levels, rounded down, and return a double[][] that should preserve the states as closely as intended for most purposes. For compressing FOV, you should generate levels with CoordPacker.generatePackingLevels() instead of manually creating the array, because some imprecision is inherent in floating point math and comparisons are often incorrect between FOV with multiple levels and exact levels generated as simply as possible. generatePackingLevels() adds a small correction to the levels to compensate for floating-point math issues, which shouldn't affect the correctness of the results for FOV radii under 100.
As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps.
To store only two states, you should use pack(), unless the double[][] divides data into on and off based on a relationship to some number other than 0.0. To (probably poorly) pack all the walls (and any cells with values higher than DijkstraMap.WALL) in a DijkstraMap's 2D array of doubles called dijkstraArray, you could callpackMulti(dijkstraArray, new double[]{DijkstraMap.WALL});
Then, you would use only the one sub-element of the returned short[][].- Parameters:
map
- a double[][] that probably was returned by FOV. If you obtained a double[][] from DijkstraMap, it will not meaningfully compress with this method unless you have very specific needs.levels
- a double[] starting with the lowest value that should be counted as "on" (the outermost cells of an FOV map that has multiple grades of brightness would be counted by this) and ascending until the last value; the last value should be highest (commonly 1.0 for FOV), and will be used for any cells higher than all the other levels values. An example is an array of: 0.25, 0.5, 0.75, 1.0- Returns:
- a packed short[][] that should, in most circumstances, be passed to unpackMultiDouble() or unpackMultiByte() when it needs to be used. The 2D array will be jagged with an outer length equal to the length of levels and sub-arrays that go from having longer lengths early on to very compact lengths by the end of the short[][].
-
packMulti
Compresses a byte[][] that stores any number of states, and an int no more than 63, returning a short[][] as described in theCoordPacker
class documentation. This short[][] can be passed tounpackMultiByte(short[][], int, int)
to restore the state at a position to the nearest state possible, capped at levelCount, and return a byte[][] that should preserve the states as closely as intended for most purposes.
As stated in the class documentation, the compressed result is intended to use as little memory as possible for most roguelike FOV maps.
To store only two states, you should use pack().- Parameters:
map
- a byte[][] that probably was returned by a specialized FOV.levelCount
- an int expressing how many levels should be present in the output; values greater than levelCount in map will be treated as the highest level.- Returns:
- a packed short[][] that should, in most circumstances, be passed to unpackMultiDouble() or unpackMultiByte() when it needs to be used. The 2D array will be jagged with an outer length equal to the length of levels and sub-arrays that go from having longer lengths early on to very compact lengths by the end of the short[][].
-
unpack
Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation. This returns a boolean[][] that stores the same values that were packed if the overload of pack() taking a boolean[][] was used. If a double[][] was compressed with pack(), the boolean[][] this returns will have true for all values greater than 0 and false for all others. If this is one of the sub-arrays compressed by packMulti(), the index of the sub-array will correspond to an index in the levels array passed to packMulti(), and any cells that were at least equal to the corresponding value in levels will be true, while all others will be false. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[] encoded by calling one of this class' packing methods on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.- Returns:
- a boolean[][] storing which cells encoded by packed are on (true) or off (false).
-
unpackDouble
Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation. This returns a double[][] that stores 1.0 for true and 0.0 for false if the overload of pack() taking a boolean[][] was used. If a double[][] was compressed with pack(), the double[][] this returns will have 1.0 for all values greater than 0 and 0.0 for all others. If this is one of the sub-arrays compressed by packMulti(), the index of the sub-array will correspond to an index in the levels array passed to packMulti(), and any cells that were at least equal to the corresponding value in levels will be 1.0, while all others will be 0.0. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[] encoded by calling one of this class' packing methods on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.- Returns:
- a double[][] storing which cells encoded by packed are on (1.0) or off (0.0).
-
unpackDoubleConical
public static double[][] unpackDoubleConical(short[] packed, int width, int height, int centerX, int centerY, double angle, double span)Decompresses a short[] returned by pack() or a sub-array of a short[][] returned by packMulti(), as described in theCoordPacker
class documentation. This returns a double[][] that stores 1.0 for true and 0.0 for false if the overload of pack() taking a boolean[][] was used. If a double[][] was compressed with pack(), the double[][] this returns will have 1.0 for all values greater than 0 and 0.0 for all others. If this is one of the sub-arrays compressed by packMulti(), the index of the sub-array will correspond to an index in the levels array passed to packMulti(), and any cells that were at least equal to the corresponding value in levels will be 1.0, while all others will be 0.0. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[] encoded by calling one of this class' packing methods on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.- Returns:
- a double[][] storing which cells encoded by packed are on (1.0) or off (0.0).
-
unpackMultiDouble
public static double[][] unpackMultiDouble(short[][] packed, int width, int height, double[] levels)Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, as described in theCoordPacker
class documentation. The length of levels and the length of the outer array of packed must be equal. However, the levels array passed to this method should not be identical to the levels array passed to packMulti(); for FOV compression, you should get an array for levels using generatePackingLevels(), but for decompression, you should create levels using generateLightLevels(), which should more appropriately fit the desired output. Reusing the levels array used to pack the FOV will usually produce values at the edge of FOV that are less than 0.01 but greater than 0, and will have a maximum value somewhat less than 1.0; neither are usually desirable, but using a different array made with generateLightLevels() will produce doubles ranging from 1.0 / levels.length to 1.0 at the highest. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[][] encoded by calling this class' packMulti() method on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.levels
- a double[] that must have the same length as packed, and will be used to assign cells in the returned double[][] based on what levels parameter was used to compress packed- Returns:
- a double[][] where the values that corresponded to the nth value in the levels parameter used to compress packed will now correspond to the nth value in the levels parameter passed to this method.
-
unpackMultiDoublePartial
public static double[][] unpackMultiDoublePartial(short[][] packed, int width, int height, double[] levels, int limit)Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, but only using the innermost indices up to limit, as described in theCoordPacker
class documentation. The length of levels and the length of the outer array of packed do not have to be equal. However, the levels array passed to this method should not be identical to the levels array passed to packMulti(); for FOV compression, you should get an array for levels using generatePackingLevels(), but for decompression, you should create levels using generateLightLevels(), which should more appropriately fit the desired output. Reusing the levels array used to pack the FOV will usually produce values at the edge of FOV that are less than 0.01 but greater than 0, and will have a maximum value somewhat less than 1.0; neither are usually desirable, but using a different array made with generateLightLevels() will produce doubles ranging from 1.0 / levels.length to 1.0 at the highest. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[][] encoded by calling this class' packMulti() method on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.levels
- a double[] that must have the same length as packed, and will be used to assign cells in the returned double[][] based on what levels parameter was used to compress packedlimit
- the number of elements to consider from levels and packed, starting from the innermost.- Returns:
- a double[][] where the values that corresponded to the nth value in the levels parameter used to compress packed will now correspond to the nth value in the levels parameter passed to this method.
-
unpackMultiDoublePartialConical
public static double[][] unpackMultiDoublePartialConical(short[][] packed, int width, int height, double[] levels, int limit, int centerX, int centerY, double angle, double span)Decompresses a short[][] returned by packMulti() and produces an approximation of the double[][] it compressed using the given levels double[] as the values to assign, but only using the innermost indices up to limit, as described in theCoordPacker
class documentation. The length of levels and the length of the outer array of packed do not have to be equal. However, the levels array passed to this method should not be identical to the levels array passed to packMulti(); for FOV compression, you should get an array for levels using generatePackingLevels(), but for decompression, you should create levels using generateLightLevels(), which should more appropriately fit the desired output. Reusing the levels array used to pack the FOV will usually produce values at the edge of FOV that are less than 0.01 but greater than 0, and will have a maximum value somewhat less than 1.0; neither are usually desirable, but using a different array made with generateLightLevels() will produce doubles ranging from 1.0 / levels.length to 1.0 at the highest. This method takes an angle and span as well as a centerX and centerY; the only values that will be greater than 0.0 in the result will be within the round-based conical section that could be produced by traveling from (centerX,centerY) along angle in a limitless line and expanding the cone to be span degrees broad (circularly), centered on angle. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[][] encoded by calling this class' packMulti() method on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.levels
- a double[] that must have the same length as packed, and will be used to assign cells in the returned double[][] based on what levels parameter was used to compress packedlimit
- the number of elements to consider from levels and packed, starting from the innermost.centerX
- the x position of the corner or origin of the conical FOVcenterY
- the y position of the corner or origin of the conical FOVangle
- the center of the conical area to limit this to, in degreesspan
- the total span of the conical area to limit this to, in degrees- Returns:
- a double[][] where the values that corresponded to the nth value in the levels parameter used to compress packed will now correspond to the nth value in the levels parameter passed to this method.
-
unpackMultiByte
Decompresses a short[][] returned by packMulti() and produces a simple 2D array where the values are bytes corresponding to 1 + the highest index into levels (that is, the original levels parameter passed to packMulti) matched by a cell, or 0 if the cell didn't match any levels during compression, as described in theCoordPacker
class documentation. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
packed
- a short[][] encoded by calling this class' packMulti() method on a 2D array.width
- the width of the 2D array that will be returned; should match the unpacked array's width.height
- the height of the 2D array that will be returned; should match the unpacked array's height.- Returns:
- a byte[][] where the values that corresponded to the nth value in the levels parameter used to compress packed will now correspond to bytes with the value n+1, or 0 if they were "off" in the original array.
-
unpackChar
Given a piece of packed data defining a region to use from that map, a char to use for "on" cells and a char to use for "off" cells, produces a 2D char array where all positions that are "off" in packed are filled with the char passed as f, and the cells that are "on" are filled with the char passed as t. Finds the bounding rectangle starting at the origin and extending to the highest x and highest y values encoded in packed, and uses that to determine the width and height of the returned 2D array.- Parameters:
packed
- a packed short array, as produced by pack()t
- the char to use for "on" positions in packedf
- the char to use for "off" positions in packed- Returns:
- a 2D char array, with dimensions determined by the bounds of packed, where any "on" cells equal t and anything else equals f.
-
unpackChar
Given a piece of packed data defining a region to use from that map, a desired width and height, a char to use for "on" cells and a char to use for "off" cells, produces a 2D char array where all positions that are "off" in packed are filled with the char passed as f, and the cells that are "on" are filled with the char passed as t.- Parameters:
packed
- a packed short array, as produced by pack()width
- the desired 2D array widthheight
- the desired 2D array heightt
- the char to use for "on" positions in packedf
- the char to use for "off" positions in packed- Returns:
- a 2D char array, width by height in dimensions, where any "on" cells equal t and anything else equals f.
-
unpackGreasedRegion
Utility method that constructs a GreasedRegion (a faster but more-memory-hungry way to encode regions) from a short array of packed data.- Parameters:
packed
- a packed short array, as produced by pack()width
- the desired GreasedRegion's widthheight
- the desired GreasedRegion's height- Returns:
- a GreasedRegion that contains the same data as packed, with the specified width and height
-
unpackIntoGreasedRegion
Utility method that fills an existing GreasedRegiontarget
with any "on" cells in the packed short arraypacked
. This method doesn't allocate unless an argument is null (then it throws a new Exception). It also won't insert any "on" cells in packed that are outside the width and height of target.- Parameters:
packed
- a packed short array, as produced by pack()target
- a GreasedRegion that will be modified in-place to include "on" cells from packed- Returns:
- target, after modifications to try to include any and all "on" cells in packed
-
unpackIntoGreasedRegion
public static GreasedRegion unpackIntoGreasedRegion(short[] packed, GreasedRegion target, int offsetX, int offsetY)Utility method that fills an existing GreasedRegiontarget
with any "on" cells in the packed short arraypacked
, inserting cells from packed at an offset when they go into target. This method doesn't allocate unless an argument is null (then it throws a new Exception). It also won't insert any "on" cells in packed that are outside the width and height of target.- Parameters:
packed
- a packed short array, as produced by pack()target
- a GreasedRegion that will be modified in-place to include "on" cells from packedoffsetX
- how much to offset x positions in packed by when they are placed into targetoffsetY
- how much to offset y positions in packed by when they are placed into target- Returns:
- target, after modifications to try to include any and all "on" cells in packed
-
queryPacked
Quickly determines if an x,y position is true or false in the given packed array, without unpacking it.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).x
- between 0 and 255, inclusivey
- between 0 and 255, inclusive- Returns:
- true if the packed data stores true at the given x,y location, or false in any other case.
-
queryPackedHilbert
Quickly determines if a Hilbert Curve index corresponds to true or false in the given packed array, without unpacking it.
Typically this method will not be needed by library-consuming code unless that code deals with Hilbert Curves in a frequent and deeply involved manner. It does have the potential to avoid converting to and from x,y coordinates and Hilbert Curve indices unnecessarily, which could matter for high-performance code.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).hilbert
- a Hilbert Curve index, such as one taken directly from a packed short[] without extra processing- Returns:
- true if the packed data stores true at the given Hilbert Curve index, or false in any other case.
-
findManyPacked
Quickly determines if an x,y position is true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.- Parameters:
x
- between 0 and 255, inclusivey
- between 0 and 255, inclusivepacked
- an array or vararg of short[], such as those returned by pack() or one of the sub-arrays in what is returned by packMulti(); null elements in packed will be skipped.- Returns:
- an OrderedSet of all packed arrays that store true at the given x,y location.
-
findManyPacked
Quickly determines if an x,y position is true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.- Parameters:
x
- between 0 and 255, inclusivey
- between 0 and 255, inclusivepacked
- a Collection of short[] (as encoded by this class); null elements in packed will be skipped.- Returns:
- an OrderedSet of all packed arrays that store true at the given x,y location.
-
regionsContain
Quickly determines if a region is contained in one of the given packed arrays, without unpacking them, and returns true if the region checking has some overlap with any of the packed arrays, or false otherwise.- Parameters:
checking
- the packed data to check for overlap with the other regionspacked
- an array or vararg of short[], such as those returned by pack() or one of the sub-arrays in what is returned by packMulti(); null elements in packed will be skipped- Returns:
- true if checking overlaps with any of the packed arrays, or false otherwise
-
regionsContain
Quickly determines if a region is contained in one of the given packed arrays, without unpacking them, and returns true if the region checking has some overlap with any of the packed arrays, or false otherwise.- Parameters:
checking
- the packed data to check for overlap with the other regionspacked
- a Collection of short[], as encoded by this class; null elements in packed will be skipped- Returns:
- true if checking overlaps with any of the packed arrays, or false otherwise
-
findManyPackedHilbert
Quickly determines if a Hilbert Curve index corresponds to true or false in one of the given packed arrays, without unpacking them, and returns a List of all packed arrays that contain the position.
Typically this method will not be needed by library-consuming code unless that code deals with Hilbert Curves in a frequent and deeply involved manner. It does have the potential to avoid converting to and from x,y coordinates and Hilbert Curve indices unnecessarily, which could matter for high-performance code.- Parameters:
hilbert
- a Hilbert Curve index, such as one taken directly from a packed short[] without extra processingpacked
- an array or vararg of short[], such as those returned by pack() or one of the sub-arrays in what is returned by packMulti(); null elements in packed will be skipped.- Returns:
- an ArrayList of all packed arrays that store true at the given x,y location.
-
allPacked
Gets all positions that are "on" in the given packed array, without unpacking it, and returns them as a Coord[].- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).- Returns:
- a Coord[], ordered by distance along the Hilbert Curve, corresponding to all "on" cells in packed.
-
allPackedHilbert
Gets all positions that are "on" in the given packed array, without unpacking it, and returns them as an array of Hilbert Curve indices.
Typically this method will not be needed by library-consuming code unless that code deals with Hilbert Curves in a frequent and deeply involved manner. It does have the potential to avoid converting to and from x,y coordinates and Hilbert Curve indices unnecessarily, which could matter for high-performance code.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).- Returns:
- a Hilbert Curve index array, in ascending distance order, corresponding to all "on" cells in packed.
-
nth
Gets the nth position that is "on" in the given packed array, without unpacking it, and returns it as a Coord. Uses Hilbert Curve ordering for the exact Hilbert Curve CoordPacker uses, so any two given Coords will always have the same before-after relationship. Returns null if n is not between 0 (inclusive) and the count of packed (exclusive), as byCoordPacker.count()
. You can technically use nth to iterate over only the Coords that are defined in some packed data, but it's drastically more efficient to store a Coord array once with allPacked(). Using nth() as an iterator is essentially running a growing portion of what allPacked() does, over and over again, until the last Coord encoded in packed takes almost as long to process as one call to allPacked(). That said, for a single Coord this can be significantly faster than getting an array with allPacked() and fetching only one item from it.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).n
- the index to get in packed- Returns:
- the nth Coord encoded as "on" by packed, ordered by distance along the Hilbert Curve, or null if n is out of bounds
-
fractionPacked
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores one of those cells as a Coord, and returns the accumulated portion of positions as a Coord[].
For purposes of finding mostly cells with a similar distance to each other but without obvious patterns, a value of 5, 6, or 7 for fraction works well for relatively-close Coords, but larger values are better for packed data with wide, expansive areas. If you want to make the regular pattern this uses impossible to discern, you can userandomSeparated()
to keep distance between Coords and sample most areas of some packed data. Values for fraction that are multiples of 4 are likely to show a pattern in large open spaces more easily.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).fraction
- the denominator of the approximate fraction of "on" cells to use- Returns:
- a Coord[] corresponding to a fraction of the "on" cells in packed.
-
randomSeparated
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores a random one of those cells as a Coord, and returns the accumulated random portion of positions as a Coord[]. Because of how this works, it is much more likely that the Coords will be dispersed so that there's a good amount of minimum distance between most Coords, while methods like randomPortion() do not make such dispersal a priority and may return tight clusters of Coords.
For purposes of finding mostly cells with a similar distance to each other but without obvious patterns, a value of at least 7 for fraction works well.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).separation
- the denominator of the approximate fraction of "on" cells to userng
- theIRNG
, such as anRNG
orGWTRNG
, to use to randomize retrieval- Returns:
- a Coord[] corresponding to a fraction of the "on" cells in packed.
-
fractionPackedHilbert
Gets the positions that are "on" in the given packed array, without unpacking it, repeatedly goes through a number of "on" cells equal to fraction and stores one of those cells as a Coord, and returns the accumulated portion of positions as an array of Hilbert Curve indices.
For purposes of finding mostly cells with a similar distance to each other but without obvious patterns, a value of 5, 6, or 7 for fraction works well.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).fraction
- the approximate fraction of "on" cells to use- Returns:
- a Hilbert Curve index array corresponding to a fraction of the "on" cells in packed.
-
apartPacked
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as a Coord[].- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).minDistance
- the minimum distance (measured 8-way, Chebyshev) between any positions this returns- Returns:
- a Coord[] corresponding to a portion of the "on" cells in packed.
-
apartPacked
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as a Coord[].- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).minDistance
- the minimum distance (measurement depends on eightWay) between any positions this returnseightWay
- true if distance should be measured equally in 8 directions, false to use 4 directions- Returns:
- a Coord[] corresponding to a portion of the "on" cells in packed.
-
apartPackedHilbert
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as an array of Hilbert Curve indices.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).minDistance
- the minimum distance (measured 8-way, Chebyshev) between any positions this returns- Returns:
- a Hilbert Curve index array corresponding to a portion of the "on" cells in packed.
-
apartPackedHilbert
Gets the positions that are "on" in the given packed array, without unpacking it, keeps only positions that are at least minDistance apart from other positions this will return, and returns the positions as an array of Hilbert Curve indices.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check due to very tight performance constraints).minDistance
- the minimum distance (measurement depends on eightWay) between any positions this returnseightWay
- true if distance should be measured equally in 8 directions, false to use 4 directions- Returns:
- a Hilbert Curve index array corresponding to a portion of the "on" cells in packed.
-
translate
Move all "on" positions in packed by the number of cells given in xMove and yMove, unless the move would take them further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge (moving any shape by an xMove greater than width or yMove greater than height will move all "on" cells to that edge, in a 1-cell thick line). Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()xMove
- distance to move the x-coordinate; can be positive or negativeyMove
- distance to move the y-coordinate; can be positive or negativewidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- a packed array that encodes "on" for cells that were moved from cells that were "on" in packed
-
expand
Expand each "on" position in packed to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. Uses 8-way movement (Chebyshev distance) unless the overload of this function that takes a boolean argument eightWay is used and that argument is false. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansion
- the positive (square) radius, in cells, to expand each cell out bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- a packed array that encodes "on" for packed and cells that expanded from cells that were "on" in packed
-
expand
public static short[] expand(short[] packed, int expansion, int width, int height, boolean eightWay)Expand each "on" position in packed to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansion
- the positive (square) radius, in cells, to expand each cell out bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the expansion should be both diagonal and orthogonal; false for just orthogonal- Returns:
- a packed array that encodes "on" for packed and cells that expanded from cells that were "on" in packed
-
retract
Finds the area made by removing the "on" positions in packed that are within the specified retraction distance of an "off" position or the edge of the map. This essentially finds a shrunken version of packed. Uses 8-way movement (Chebyshev distance) unless the overload of this function that takes a boolean argument eightWay is used and that argument is false. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()retraction
- the positive (square) radius, in cells, to pull each cell in bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- a short[] that encodes "on" for cells that were "on" in packed and were far enough from an "off" cell
-
retract
public static short[] retract(short[] packed, int retraction, int width, int height, boolean eightWay)Finds the area made by removing the "on" positions in packed that are within the specified retraction distance of an "off" position or the edge of the map. This essentially finds a shrunken version of packed. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()retraction
- the positive (square) radius, in cells, to pull each cell in bywidth
- the maximum width; cells outside this are considered "off" for this method's purposesheight
- the maximum height; cells outside this are considered "off" for this method's purposeseightWay
- true if the retraction should be both diagonal and orthogonal; false for just orthogonal- Returns:
- a packed array that encodes "on" for packed and cells that expanded from cells that were "on" in packed
-
fringe
Finds the area around the cells encoded in packed, without including those cells. For each "on" position in packed, expand it to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. If a cell is "on" in packed, it will always be "off" in the result. Uses 8-way movement (Chebyshev distance) unless the overload of this function that takes a boolean argument eightWay is used and that argument is false. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansion
- the positive (square-shaped) radius, in cells, to expand each cell out bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- a packed array that encodes "on" for cells that were pushed from the edge of packed's "on" cells
-
fringe
public static short[] fringe(short[] packed, int expansion, int width, int height, boolean eightWay)Finds the area around the cells encoded in packed, without including those cells. For each "on" position in packed, expand it to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. If a cell is "on" in packed, it will always be "off" in the result. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansion
- the positive (square-shaped) radius, in cells, to expand each cell out bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the expansion should be both diagonal and orthogonal; false for just orthogonal- Returns:
- a packed array that encodes "on" for cells that were pushed from the edge of packed's "on" cells
-
fringe
public static short[] fringe(short[] packed, int expansion, int width, int height, boolean eightWay, boolean drop)Finds the area around the cells encoded in packed, without including those cells. For each "on" position in packed, expand it to cover a a square with side length equal to 1 + expansion * 2, centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is removed if drop is true, or stopped at the edge if drop is false. If a cell is "on" in packed, it will always be "off" in the result. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansion
- the positive (square-shaped) radius, in cells, to expand each cell out bywidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the expansion should be both diagonal and orthogonal; false for just orthogonaldrop
- true to drop cells that would expand into negative coordinates or past width/height, false to stop their expansion early- Returns:
- a packed array that encodes "on" for cells that were pushed from the edge of packed's "on" cells
-
fringes
Finds the concentric areas around the cells encoded in packed, without including those cells. For each "on" position in packed, expand it to cover a a square with side length equal to 1 + n * 2, where n starts at 1 and goes up to include the expansions parameter, with each expansion centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. If a cell is "on" in packed, it will always be "off" in the results. Returns a new packed short[][] where the outer array has length equal to expansions and the inner arrays are packed data encoding a one-cell-wide concentric fringe region. Uses 8-way measurement. Does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansions
- the positive (square-shaped) radius, in cells, to expand each cell out by, also the length of the outer array returned by this methodwidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- an array of packed arrays that encode "on" for cells that were pushed from the edge of packed's "on" cells; the outer array will have length equal to expansions, and inner arrays will normal packed data
-
fringes
public static short[][] fringes(short[] packed, int expansions, int width, int height, boolean eightWay)Finds the concentric areas around the cells encoded in packed, without including those cells. For each "on" position in packed, expand it to cover a a square or diamond with radius equal to n, where n starts at 1 and goes up to include the expansions parameter, with each expansion centered on the original "on" position, unless the expansion would take a cell further than 0, width - 1 (for xMove) or height - 1 (for yMove), in which case that cell is stopped at the edge. If a cell is "on" in packed, it will always be "off" in the results. Returns a new packed short[][] where the outer array has length equal to expansions and the inner arrays are packed data encoding a one-cell-wide concentric fringe region. Does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()expansions
- the positive (square-shaped) radius, in cells, to expand each cell out by, also the length of the outer array returned by this methodwidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the expansion should be both diagonal and orthogonal; false for just orthogonal- Returns:
- an array of packed arrays that encode "on" for cells that were pushed from the edge of packed's "on" cells; the outer array will have length equal to expansions, and inner arrays will normal packed data
-
surface
Finds the area consisting of the "on" positions in packed that are within the specified depth distance of an "off" position or the edge of the map. This essentially finds the part of packed that is close to its edge. Uses 8-way movement (Chebyshev distance) unless the overload of this function that takes a boolean argument eightWay is used and that argument is false. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()depth
- the positive (square) radius, in cells, to go inward from an "off" cell into the "in" cellswidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- a short[] that encodes "on" for cells that were "on" in packed and were close enough to an "off" cell
-
surface
Finds the area consisting of the "on" positions in packed that are within the specified depth distance of an "off" position or the edge of the map. This essentially finds the part of packed that is close to its edge. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()depth
- the positive (square) radius, in cells, to go inward from an "off" cell into the "in" cellswidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the retraction should be both diagonal and orthogonal; false for just orthogonal- Returns:
- a short[] that encodes "on" for cells that were "on" in packed and were close enough to an "off" cell
-
surfaces
Finds the concentric, progressively-smaller surfaces of packed as if packed was shrinking with each iteration. Essentially, this is the inverse of fringes, where fringe finds a ring around packed and fringes finds concentric rings around growing versions of packed, while surface finds a ring at the edge and surfaces finds rings at the edge of shrinking versions of packed. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()depth
- the positive (square) radius, in cells, to go inward from an "off" cell into the "in" cellswidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1- Returns:
- an array of packed short[] that each encodes "on" for cells that were "on" in packed and were at a distance between 1 and depth to an "off" cell
-
surfaces
public static short[][] surfaces(short[] packed, int depth, int width, int height, boolean eightWay)Finds the concentric, progressively-smaller surfaces of packed as if packed was shrinking with each iteration. Essentially, this is the inverse of fringes, where fringe finds a ring around packed and fringes finds concentric rings around growing versions of packed, while surface finds a ring at the edge and surfaces finds rings at the edge of shrinking versions of packed. Returns a new packed short[] and does not modify packed.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti()depth
- the positive (square) radius, in cells, to go inward from an "off" cell into the "in" cellswidth
- the maximum width; if a cell would move to x at least equal to width, it stops at width - 1height
- the maximum height; if a cell would move to y at least equal to height, it stops at height - 1eightWay
- true if the retraction should be both diagonal and orthogonal; false for just orthogonal- Returns:
- an array of packed short[] that each encodes "on" for cells that were "on" in packed and were at a distance between 1 and depth to an "off" cell
-
flood
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a Manhattan (diamond) radius equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Notably, if a small area is not present within bounds, then the flood will move around the "hole" similarly to DijkstraMap's behavior; essentially, it needs to expand around the hole to get to the other side, and this takes more steps of expansion than crossing straight over. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to flood-fill; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromexpansion
- the positive (square) radius, in cells, to expand each cell out by- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion Manhattan distance from a Coord in start
-
flood
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius (if eightWay is true, it uses Chebyshev distance; if it is false, it uses Manhattan distance) equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Notably, if a small area is not present within bounds, then the flood will move around the "hole" similarly to DijkstraMap's behavior; essentially, it needs to expand around the hole to get to the other side, and this takes more steps of expansion than crossing straight over. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to flood-fill; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromexpansion
- the positive (square) radius, in cells, to expand each cell out byeightWay
- true to flood-fill out in all eight directions at each step, false for just orthogonal- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion either Chebyshev (if eightWay is true) or Manhattan (otherwise) distance from a Coord in start
-
spill
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, an IRNG, and a volume in cells, expands a random cell in start in a random Manhattan (diamond) direction equal, then continues to expand from random cells in start or the expanded area until it has filled volume cells, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Notably, if a small area is not present within bounds, then the spill will move around the "hole" similarly to DijkstraMap's behavior; essentially, it needs to expand around the hole to get to the other side, and this takes more steps of expansion than crossing straight over.
Could also be given a name like randomizedFlood(), but spill() is used by the Spill class that does this too.
Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to random-flood-fill; often floorsstart
- a packed array that encodes position(s) that the random-flood will spread outward fromvolume
- the total number of cells to try to fillrng
- theIRNG
, such as anRNG
orGWTRNG
, used to generate random numbers for the flooding- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion Manhattan distance from a Coord in start
-
radiate
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a Manhattan (diamond) radius equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Though this is otherwise similar to flood(), radiate() behaves like FOV and will not move around obstacles and will instead avoid expanding if it would go into any cell that cannot be reached by a straight line (drawn directly, not in grid steps) that is mostly unobstructed. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to flood-fill; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromexpansion
- the positive (square) radius, in cells, to expand each cell out by- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion Manhattan distance from a Coord in start
-
radiate
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius, with a shape determined by metric, equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Though this is otherwise similar to flood(), radiate() behaves like FOV and will not move around obstacles and will instead avoid expanding if it would go into any cell that cannot be reached by a straight line (drawn directly, not in grid steps) that is mostly unobstructed. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to flood-fill; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromexpansion
- the positive (square) radius, in cells, to expand each cell out bymetric
- a Radius that defines how this should expand, SQUARE for 8-way, DIAMOND for 4-way, CIRCLE for Euclidean expansion (not guaranteed to be perfectly circular)- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion Manhattan distance from a Coord in start
-
radiate
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and an amount of expansion, expands each cell in start by a radius, with a square shape if eightWay is true or a diamond otherwise, equal to expansion, limiting any expansion to within bounds and returning the final expanded (limited) packed data. Though this is otherwise similar to flood(), radiate() behaves like FOV and will not move around obstacles and will instead avoid expanding if it would go into any cell that cannot be reached by a straight line (drawn directly, not in grid steps) that is mostly unobstructed. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the maximum extent of the region to flood-fill; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromexpansion
- the positive (square) radius, in cells, to expand each cell out byeightWay
- true to flood-fill out in all eight directions at each step, false for just orthogonal- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and are within expansion either Chebyshev (if eightWay is true) or Manhattan (otherwise) distance from a Coord in start
-
reachable
Given a packed array encoding a larger area, a packed array encoding one or more points inside bounds, and a Reach object that determines targeting constraints, gets all cells contained within bounds that can be targeted from a cell in start using the rules defined by reach. Though this is otherwise similar to flood(), reachable() behaves like FOV and will not move around obstacles and will instead avoid expanding if it would go into any cell that cannot be reached by a straight line (drawn directly, not in grid steps) that is mostly unobstructed. This does not behave quite like FOV if an AimLimit has been set in reach to any value other than null or AimLimit.FREE; in these cases it requires an exactly straight orthogonal or diagonal line without obstructions, checking only cells along the precise path. For diagonals and eight-way targeting, this means it can target through walls that only meet at a perpendicular diagonal, such as an X shape where one line is a one-cell-thick diagonal wall and the other is the targeting line. This is normally only allowed in some games and only if they use Chebyshev (Radius.SQUARE) distance, so be advised that it may not be desirable behavior. Returns a new packed short[] and does not modify bounds or start.- Parameters:
bounds
- packed data representing the max extent of the region to check for reach-ability; often floorsstart
- a packed array that encodes position(s) that the flood will spread outward fromreach
- aReach
object that determines minimum and maximum range, distance metric, and AimLimit- Returns:
- a packed array that encodes "on" for cells that are "on" in bounds and can be targeted from a cell in start using the given Reach
-
rectangle
Given a width and height, returns a packed array that encodes "on" for the rectangle from (0,0) to (width - 1, height - 1). Primarily useful with intersectPacked() to ensure things like negatePacked() that can encode "on" cells in any position are instead limited to the bounds of the map.- Parameters:
width
- the width of the rectangleheight
- the height of the rectangle- Returns:
- a packed short[] encoding "on" for all cells with x less than width and y less than height.
-
rectangle
Given x, y, width and height, returns a packed array that encodes "on" for the rectangle from (x,y) to (width + x - 1, height + y - 1). Primarily useful with intersectPacked() to ensure things like negatePacked() that can encode "on" cells in any position are instead limited to the bounds of the map, but also handy for basic "box drawing" for other uses.- Parameters:
x
- the minimum x coordinatey
- the minimum y coordinatewidth
- the width of the rectangleheight
- the height of the rectangle- Returns:
- a packed short[] encoding "on" for all cells between (x,y) and (x+width-1,y+height-1).
-
rectangleHilbert
Given x, y, width and height, returns an array of all Hilbert distance within the rectangle from (x,y) to (width + x - 1, height + y - 1).- Parameters:
x
- the minimum x coordinatey
- the minimum y coordinatewidth
- the width of the rectangleheight
- the height of the rectangle- Returns:
- a short[] that is not packed, and instead stores individual Hilbert distances in the rectangle
-
circle
Given a center and radius for a circle, plus the width and height for the map boundaries, returns the packed data that encodes the circle.- Parameters:
center
- center position of the circleradius
- radius to extend in all directions from centerwidth
- the maximum width of the map (exclusive); the circle will not extend past this or below 0height
- the maximum height of the map (exclusive); the circle will not extend past this or below 0- Returns:
- a packed short[] encoding "on" for all elements inside the circle
-
count
Counts the number of "on" cells encoded in a packed array without unpacking it.- Parameters:
packed
- a packed short array, as produced by pack()- Returns:
- the number of "on" cells.
-
count
Counts the number of cells encoding a boolean equal to wanted in a packed array without unpacking it.- Parameters:
packed
- a packed short array, as produced by pack()wanted
- the boolean you want to count, true for "on" and false for "off"- Returns:
- the number of cells that encode a value equal to wanted.
-
covered
Finds how many cells are encoded in a packed array (both on and off) without unpacking it.- Parameters:
packed
- a packed short array, as produced by pack()- Returns:
- the number of cells that are encoded explicitly in the packed data as either on or off.
-
bounds
Finds the minimum bounding rectangle for a packed array without unpacking it. Returns a Coord array with 2 elements: the minimum-x/minimum-y Coord corner of the bounds, then the maximum-x/maximum-y Coord corner. Both array elements will be the Coord (-1,-1) if the packed array does not encode any "on" values (all empty).- Parameters:
packed
- a packed short array, as produced by pack()- Returns:
- a 2-element Coord array starting with the bounds' minimum corner and followed by the maximum corner
-
mask
Given a 2D char array for a map, a piece of packed data defining a region to use from that map, and a filler char, produces a 2D char array where all positions that are "off" in packed are filled with filler, and the rest are the same as in map.- Parameters:
map
- a 2D char array that will not be modifiedpacked
- a packed short array, as produced by pack()filler
- the char to use for "off" positions in packed- Returns:
- a 2D char array similar to map but with any "off" positions in packed replaced with filler
-
unionPacked
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in either left or in right, and only encodes "off" for cells that were off in both. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when merging two pieces of packed data.- Parameters:
left
- A packed array such as one produced by pack()right
- A packed array such as one produced by pack()- Returns:
- A packed array that encodes "on" for all cells that were "on" in either left or right
-
intersectPacked
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in both left and in right, and encodes "off" for cells that were off in either array. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding the intersection of two pieces of packed data.- Parameters:
left
- A packed array such as one produced by pack()right
- A packed array such as one produced by pack()- Returns:
- A packed array that encodes "on" for all cells that were "on" in both left and right
-
isEmpty
Checks if no cells are encoded as "on" in packed.- Parameters:
packed
- a packed array such as one produced by pack()- Returns:
- false if there is at least one "on" cell in packed; true if there are no "on" cells
-
intersects
Given two packed short arrays, left and right, this returns true if they encode any overlapping area (their areas intersect), or false if they do not overlap at all (they don't intersect). This is more efficient than calculating the intersection with intersectPacked() just to check if it is non-empty, since this method can short-circuit and return true the moment it finds an intersection, plus it needs less overhead (slightly) to do so.- Parameters:
left
- A packed array such as one produced by pack()right
- A packed array such as one produced by pack()- Returns:
- The boolean true if left and right overlap at all, or false if they lack any intersecting area
-
negatePacked
Given one packed short array, this produces a packed short array that is the exact opposite of the one passed in, that is, every "on" cell becomes "off" and every "off" cell becomes "on", including cells that were "off" because they were beyond the boundaries of the original 2D array passed to pack() or a similar method. This method does not do any unpacking (which can be somewhat computationally expensive), and actually requires among the lowest amounts of computation to get a result of any methods in CoordPacker. However, because it will cause cells to be considered "on" that would cause an exception if directly converted to x,y positions and accessed in the source 2D array, this method should primarily be used in conjunction with operations such as intersectPacked(), or have the checking for boundaries handled internally by unpack() or related methods such as unpackMultiDouble().- Parameters:
original
- A packed array such as one produced by pack()- Returns:
- A packed array that encodes "on" all cells that were "off" in original
-
differencePacked
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" in left but "off" in right, and encodes "off" for cells that were "on" in right or "off" in left. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding a region of one packed array that is not contained in another packed array.- Parameters:
left
- A packed array such as one produced by pack()right
- A packed array such as one produced by pack()- Returns:
- A packed array that encodes "on" for all cells that were "on" in left and "off" in right
-
xorPacked
Given two packed short arrays, left and right, this produces a packed short array that encodes "on" for any cell that was "on" only in left or only in right, but not a cell that was "off" in both or "on" in both. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when performing an exclusive-or operation on two pieces of packed data.
Could more-correctly be called exclusiveDisjunctionPacked to match the other terms, but... seriously?- Parameters:
left
- A packed array such as one produced by pack()right
- A packed array such as one produced by pack()- Returns:
- A packed array that encodes "on" for all cells such that left's cell ^ right's cell returns true
-
packOne
Returns a new packed short[] containing the Hilbert distance hilbert as "on", and all other cells "off". Much more efficient than packSeveral called with only one argument.- Parameters:
hilbert
- a Hilbert distance that will be encoded as "on"- Returns:
- the point given to this encoded as "on" in a packed short array
-
packOne
Returns a new packed short[] containing the Coord point as "on", and all other cells "off". Much more efficient than packSeveral called with only one argument.- Parameters:
point
- a Coord that will be encoded as "on"- Returns:
- the point given to this encoded as "on" in a packed short array
-
packOne
Returns a new packed short[] containing the given x,y cell as "on", and all other cells "off". Much more efficient than packSeveral called with only one argument.- Parameters:
x
- the x component of the point that will be encoded as "on"y
- the y component of the point that will be encoded as "on"- Returns:
- the point given to this encoded as "on" in a packed short array
-
packSeveral
Returns a new packed short[] containing the Hilbert distances in hilbert as "on" cells, and all other cells "off"- Parameters:
hilbert
- a vararg or array of Hilbert distances that will be encoded as "on"- Returns:
- the points given to this encoded as "on" in a packed short array
-
packSeveral
Returns a new packed short[] containing the Coords in points as "on" cells, and all other cells "off"- Parameters:
points
- a vararg or array of Coords that will be encoded as "on"- Returns:
- the points given to this encoded as "on" in a packed short array
-
packSeveral
Returns a new packed short[] containing the Coords in points as "on" cells, and all other cells "off"- Parameters:
points
- a Collection of Coords that will be encoded as "on"- Returns:
- the points given to this encoded as "on" in a packed short array
-
insertPacked
Given one packed short array, original, and a Hilbert Curve index, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by hilbert, and encodes "off" for cells that were "off" in original and are not the cell hilbert refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding a region of one packed array that is not contained in another packed array.- Parameters:
original
- A packed array such as one produced by pack()hilbert
- A Hilbert Curve index that should be inserted into the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original or correspond to hilbert
-
insertPacked
Given one packed short array, original, and a position as x,y numbers, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by x and y, and encodes "off" for cells that were "off" in original and are not the cell x and y refer to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding a region of one packed array that is not contained in another packed array.- Parameters:
original
- A packed array such as one produced by pack()x
- The x position at which to insert the "on" celly
- The y position at which to insert the "on" cell- Returns:
- A packed array that encodes "on" for all cells that are "on" in original or correspond to x,y
-
insertSeveralPacked
Given one packed short array, original, and a number of Hilbert Curve indices, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of hilbert, and encodes "off" for cells that were "off" in original and are not in any cell hilbert refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Hilbert Curve indices, possibly nearby each other but just as possibly not, that you need inserted into a packed array.- Parameters:
original
- A packed array such as one produced by pack()hilbert
- an array or vararg of Hilbert Curve indices that should be inserted into the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original or are contained in hilbert
-
insertSeveralPacked
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of points, and encodes "off" for cells that were "off" in original and are not in any cell points refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Coords, possibly nearby each other but just as possibly not, that you need inserted into a packed array.- Parameters:
original
- A packed array such as one produced by pack()points
- an array or vararg of Coords that should be inserted into the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original or are contained in hilbert
-
insertSeveralPacked
Given one packed short array, original, and a Collection of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, always encodes "on" for the position referred to by any element of points, and encodes "off" for cells that were "off" in original and are not in any cell points refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Coords, possibly nearby each other but just as possibly not, that you need inserted into a packed array.- Parameters:
original
- A packed array such as one produced by pack()points
- an array or vararg of Coords that should be inserted into the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original or are contained in hilbert
-
removePacked
Given one packed short array, original, and a Hilbert Curve index, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was the position referred to by hilbert, and encodes "off" for cells that were "off" in original or are the cell hilbert refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding a region of one packed array that is not contained in another packed array.- Parameters:
original
- A packed array such as one produced by pack()hilbert
- A Hilbert Curve index that should be removed from the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original and don't correspond to hilbert
-
removePacked
Given one packed short array, original, and a position as x,y numbers, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was the position referred to by x and y, and encodes "off" for cells that were "off" in original or are the cell x and y refer to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when finding a region of one packed array that is not contained in another packed array.- Parameters:
original
- A packed array such as one produced by pack()x
- The x position at which to remove any "on" celly
- The y position at which to remove any "on" cell- Returns:
- A packed array that encodes "on" for all cells that are "on" in original and don't correspond to x,y
-
removeSeveralPacked
Given one packed short array, original, and a number of Hilbert Curve indices, hilbert, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by hilbert, and encodes "off" for cells that were "off" in original and are a cell hilbert refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Hilbert Curve indices, possibly nearby each other but just as possibly not, that you need removed from a packed array.- Parameters:
original
- A packed array such as one produced by pack()hilbert
- an array or vararg of Hilbert Curve indices that should be inserted into the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original and aren't contained in hilbert
-
removeSeveralPacked
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by an element in points, and encodes "off" for cells that were "off" in original and are a cell points refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Hilbert Curve indices, possibly nearby each other but just as possibly not, that you need removed from a packed array.- Parameters:
original
- A packed array such as one produced by pack()points
- an array or vararg of Coords that should be removed from the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original and aren't contained in points
-
removeSeveralPacked
Given one packed short array, original, and a number of Coords, points, this produces a packed short array that encodes "on" for any cell that was "on" in original, unless it was a position referred to by an element in points, and encodes "off" for cells that were "off" in original and are a cell points refers to. This method does not do any unpacking (which can be somewhat computationally expensive) and so should be strongly preferred when you have several Hilbert Curve indices, possibly nearby each other but just as possibly not, that you need removed from a packed array.- Parameters:
original
- A packed array such as one produced by pack()points
- a Collection of Coords that should be removed from the result- Returns:
- A packed array that encodes "on" for all cells that are "on" in original and aren't contained in points
-
split
Given a packed data array that encodes multiple unconnected "on" areas, this finds each isolated area (areas that are only adjacent diagonally are considered separate from each other) and returns it as an element in an ArrayList of short[], with one short[] array per isolated area. Useful when you have, for example, all the rooms in a dungeon with their connecting corridors removed, but want to separate the rooms. You can get the aforementioned data assuming a bare dungeon called map with WIDTH and HEIGHT constants using:
short[] floors = pack(map, '.'), rooms = flood(floors, retract(floors, 1, WIDTH, HEIGHT, true), 2, false), corridors = differencePacked(floors, rooms), doors = intersectPacked(rooms, fringe(corridors, 1, WIDTH, HEIGHT, false));
You can then get all rooms as separate regions withList<short[]> apart = split(rooms);
, or substitutesplit(corridors)
to get the corridors. The room-finding technique works by shrinking floors by a radius of 1 (8-way), which causes thin areas like corridors of 2 or less width to be removed, then flood-filling the floors out from the area that produces by 2 cells (4-way this time) to restore the original size of non-corridor areas (plus some extra to ensure odd shapes are kept). Corridors are obtained by removing the rooms from floors. The example code also gets the doors (which overlap with rooms, not corridors) by finding where the a room and a corridor are adjacent. This technique is used with some enhancements in the RoomFinder class.- Parameters:
packed
- a packed data array that probably encodes multiple unconnected "on" areas- Returns:
- an ArrayList of short[] containing each unconnected area from packed as a short[] element
- See Also:
for a class that uses this technique without exposing CoordPacker
-
removeIsolated
-
randomSample
Gets a random subset of positions that are "on" in the given packed array, without unpacking it, and returns them as a Coord[]. Random numbers are generated by the rng parameter.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check).fraction
- the likelihood to return one of the "on" cells, from 0.0 to 1.0rng
- the random number generator used to decide random factors.- Returns:
- a Coord[], ordered by distance along the Hilbert Curve, corresponding to a random section of "on" cells in packed that has a random length approximately equal to the count of all "on" cells in packed times fraction.
-
singleRandom
Gets a single randomly chosen position that is "on" in the given packed array, without unpacking it, and returns it as a Coord or returns null of the array is empty. Random numbers are generated by the rng parameter. More efficient in most cases than randomSample(), and will always return at least one Coord for non-empty arrays.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check).rng
- the random number generator used to decide random factors- Returns:
- a Coord corresponding to a random "on" cell in packed, or the Coord (-1, -1) if packed is empty
-
randomPortion
Gets a fixed number of randomly chosen positions that are "on" in the given packed array, without unpacking it, and returns a List of Coord with a count equal to size (or less if there aren't enough "on" cells). Random numbers are generated by the rng parameter. This orders the returned array in the order the Hilbert Curve takes, and you may want to callIRNG.shuffleInPlace(List)
with it as a parameter to randomize the order.- Parameters:
packed
- a short[] returned by pack() or one of the sub-arrays in what is returned by packMulti(); must not be null (this method does not check).size
- the desired size of the List to return; may be smaller if there aren't enough elementsrng
- the random number generator used to decide random factors.- Returns:
- a List of Coords, ordered by distance along the Hilbert Curve, corresponding to randomly "on" cells in packed, with a length equal to the smaller of size and the count of all "on" cells in packed
-
sumMany
Takes multiple pieces of packed data as short[], encoded by pack() or another similar method of this class, and generates a 2D int array with the specified width and height and a starting value of 0 for all elements, then where every occurrence of a cell as "on" in a piece of packed data increments the cell's value in the returned array. Width and height do not technically need to match the dimensions of the original 2D array, but under most circumstances where they don't match, the data produced will be junk.- Parameters:
width
- the width of the 2D array that will be returned; should match the unpacked array's widthheight
- the height of the 2D array that will be returned; should match the unpacked array's heightmany
- a vararg or array of short[] encoded by calling one of this class' packing methods on a 2D array- Returns:
- an int[][] storing at least 0 for all cells, plus 1 for every element of packed that has that cell "on"
-
printPacked
Quick utility method for printing packed data as a grid of 1 (on) and/or 0 (off). Useful primarily for debugging.- Parameters:
packed
- a packed short[] such as one produced by pack()width
- the width of the packed 2D arrayheight
- the height of the packed 2D array
-
printCompressedData
-
encodeASCII
Encodes a short array of packed data as a (larger, more memory-hungry) ASCII string, which can be decoded using CoordPacker.decodeASCII() . Uses 64 printable chars, from '?' (ASCII 63) to '~' (ASCII 126).- Parameters:
packed
- a packed data item produced by pack() or some other method from this class.- Returns:
- a printable String, which can be decoded with CoordPacker.decodeASCII()
-
decodeASCII
Given a String specifically produced by CoordPacker.encodeASCII(), this will produce a packed data array.- Parameters:
text
- a String produced by CoordPacker.encodeASCII(); this will almost certainly fail on other strings.- Returns:
- the packed data as a short array that was originally used to encode text
-
encodeBraille
Encodes a short array of packed data as a (larger, slightly more memory-hungry) Unicode string using only Braille characters, which can be decoded using CoordPacker.decodeBraille(). Uses 256 semi-printable chars, from 0x2800 to 0x28FF, which allows UTF-8 encoding (and some other encodings) to more efficiently store the data. These are only semi-printable because many fonts do not support Braille, and 0x2800 is sometimes printed equivalently to a space char (or sometimes as 8 small dots or open circles, which is preferable). Braille was chosen because it's available as a full Unicode block of 256 characters with no gaps or chars that require special treatment, like newlines and carriage returns.- Parameters:
packed
- a packed data item produced by pack() or some other method from this class.- Returns:
- a semi-printable String, which can be decoded with CoordPacker.decodeBraille()
-
decodeBraille
Given a String specifically produced by CoordPacker.encodeBraille(), this will produce a packed data array. Uses 256 semi-printable chars, from 0x2800 to 0x28FF, which allows UTF-8 encoding (and some other encodings) to more efficiently store the data. These are only semi-printable because many fonts do not support Braille, and 0x2800 is sometimes printed equivalently to a space char (or sometimes as 8 small dots or open circles, which is preferable). Braille was chosen because it's available as a full Unicode block of 256 characters with no gaps or chars that require special treatment, like newlines and carriage returns.- Parameters:
text
- a String produced by CoordPacker.encodeBraille(); this will almost certainly fail on other strings.- Returns:
- the packed data as a short array that was originally used to encode text
-
grayEncode
Encode a number n as a Gray code; Gray codes have a relation to the Hilbert curve and may be useful. Source: http://xn--2-umb.com/15/hilbert , http://aggregate.org/MAGIC/#Gray%20Code%20Conversion- Parameters:
n
- any int- Returns:
- the gray code for n
-
grayDecode
Decode a number from a Gray code n; Gray codes have a relation to the Hilbert curve and may be useful. Source: http://xn--2-umb.com/15/hilbert , http://aggregate.org/MAGIC/#Gray%20Code%20Conversion- Parameters:
n
- a gray code, as produced by grayEncode- Returns:
- the decoded int
-
posToHilbert
Takes an x, y position and returns the length to travel along the 256x256 Hilbert curve to reach that position. This assumes x and y are between 0 and 255, inclusive. This uses a lookup table for the 256x256 Hilbert Curve, which should make it faster than calculating the distance along the Hilbert Curve repeatedly. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
x
- between 0 and 255 inclusivey
- between 0 and 255 inclusive- Returns:
- the distance to travel along the 256x256 Hilbert Curve to get to the given x, y point.
-
posToHilbert3D
Takes an x, y, z position and returns the length to travel along the 8x8x8 Hilbert curve to reach that position. This assumes x, y, and z are between 0 and 7, inclusive. This uses a lookup table for the 8x8x8 Hilbert Curve, which should make it faster than calculating the distance along the Hilbert Curve repeatedly. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
x
- between 0 and 7 inclusivey
- between 0 and 7 inclusivez
- between 0 and 7 inclusive- Returns:
- the distance to travel along the 8x8x8 Hilbert Curve to get to the given x, y, z point.
-
posToMoore
Takes an x, y position and returns the length to travel along the 16x16 Moore curve to reach that position. This assumes x and y are between 0 and 15, inclusive. This uses a lookup table for the 16x16 Moore Curve, which should make it faster than calculating the distance along the Moore Curve repeatedly.- Parameters:
x
- between 0 and 15 inclusivey
- between 0 and 15 inclusive- Returns:
- the distance to travel along the 16x16 Moore Curve to get to the given x, y point.
-
mortonToHilbert
Takes a position as a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the length to travel along the 256x256 Hilbert Curve to reach that position. This uses 16 bits of the Morton code and requires that the code is non-negative. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
morton
- a Morton code that interleaves two 8-bit unsigned numbers, with x as index1 and y as index2.- Returns:
- a distance to travel down the Hilbert Curve to reach the location that can be decoded from morton.
-
hilbertToMorton
Takes a distance to travel along the 256x256 Hilbert curve and returns a Morton code representing the position in 2D space that corresponds to that point on the Hilbert Curve; the Morton code will have interleaved x and y bits and x in the least significant bit. This uses a lookup table for the 256x256 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter hilbert is an int but only 16 unsigned bits are used.- Parameters:
hilbert
- a distance to travel down the Hilbert Curve- Returns:
- a Morton code that stores x and y interleaved; can be converted to a Coord with other methods.
-
hilbertToCoord
Takes a distance to travel along the 256x256 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve. This uses a lookup table for the 256x256 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter hilbert is an int but only 16 unsigned bits are used.- Parameters:
hilbert
- a distance to travel down the Hilbert Curve- Returns:
- a Coord corresponding to the position in 2D space at the given distance down the Hilbert Curve
-
mooreToCoord
Takes a distance to travel along the 16x16 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve. This uses a lookup table for the 16x16 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter moore is an int but only 8 unsigned bits are used, and since the Moore Curve loops, it is calculated asmoore & 255
.- Parameters:
moore
- a distance to travel down the Moore Curve- Returns:
- a Coord corresponding to the position in 2D space at the given distance down the Hilbert Curve
-
coordToHilbert
Takes a position as a Coord called pt and returns the length to travel along the 256x256 Hilbert curve to reach that position. This assumes pt.x and pt.y are between 0 and 255, inclusive. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
pt
- a Coord with values between 0 and 255, inclusive- Returns:
- a distance from the start of the 256x256 Hilbert curve to get to the position of pt
-
coordToMoore
Takes a position as a Coord called pt and returns the length to travel along the 16x16 Moore curve to reach that position. This assumes pt.x and pt.y are between 0 and 15, inclusive.- Parameters:
pt
- a Coord with values between 0 and 15, inclusive- Returns:
- a distance from the "start" of the 16x16 Moore curve to get to the position of pt
-
mortonEncode3D
-
mortonDecode3D
-
mortonBitDecode3D
-
getXMoore3D
Gets the x coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index
- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n
- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the x coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
getYMoore3D
Gets the y coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index
- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n
- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the y coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
getZMoore3D
Gets the z coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index
- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n
- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the z coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
zEncode
Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit. With this method, index1 and index2 can have up to 8 bits. This returns a 16-bit Morton code and WILL encode information in the sign bit if the inputs are large enough. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
index1
- a non-negative integer using at most 8 bits, to be placed in the "x" slotsindex2
- a non-negative integer using at most 8 bits, to be placed in the "y" slots- Returns:
- a Morton code/Z-Code that interleaves the two numbers into one 16-bit short
-
mortonEncode
Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit. With this method, index1 and index2 can have up to 8 bits. This returns a 32-bit Morton code but only uses 16 bits, and will not encode information in the sign bit. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
index1
- a non-negative integer using at most 8 bits, to be placed in the "x" slotsindex2
- a non-negative integer using at most 8 bits, to be placed in the "y" slots- Returns:
- a Morton code that interleaves the two numbers as one 32-bit int, but only in 16 bits of it
-
mortonDecode
Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position. This uses 16 bits of the Morton code and requires that the code is non-negative. Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
morton
- an int containing two interleaved numbers, from 0 to 255 each- Returns:
- a Coord matching the x and y extracted from the Morton code
-
zDecode
Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position. This takes a a 16-bit Z-Code with data in the sign bit, as returned by zEncode(). Source: http://and-what-happened.blogspot.com/2011/08/fast-2d-and-3d-hilbert-curves-and.html- Parameters:
morton
- a short containing two interleaved numbers, from 0 to 255 each- Returns:
- a Coord matching the x and y extracted from the Morton code
-