Package squidpony.squidmath
Class GreasedRegion
java.lang.Object
squidpony.squidgrid.zone.Zone.Skeleton
squidpony.squidmath.GreasedRegion
- All Implemented Interfaces:
Serializable
,Iterable<Coord>
,Collection<Coord>
,MutableZone
,Zone
public class GreasedRegion extends Zone.Skeleton implements Collection<Coord>, Serializable, MutableZone
Region encoding of on/off information about areas using bitsets; uncompressed (fatty), but fast (greased lightning).
This can handle any size of 2D data, and is not strictly limited to 256x256 as CoordPacker is. It stores several long
arrays and uses each bit in one of those numbers to represent a single point, though sometimes this does waste bits
if the height of the area this encodes is not a multiple of 64 (if you store a 80x64 map, this uses 80 longs; if you
store an 80x65 map, this uses 160 longs, 80 for the first 64 rows and 80 more to store the next row). It's much
faster than CoordPacker at certain operations (anything that expands or retracts an area, including
Each GreasedRegion is mutable, and instance methods typically modify that instance and return it for chaining. There are exceptions, usually where multiple GreasedRegion values are returned and the instance is not modified.
Typical usage involves constructing a GreasedRegion from some input data, like a char[][] for a map or a double[][] from DijkstraMap, and modifying it spatially with expand(), retract(), flood(), etc. It's common to mix in data from other GreasedRegions with and() (which gets the intersection of two GreasedRegions and stores it in one), or() (which is like and() but for the union), xor() (like and() but for exclusive or, finding only cells that are on in exactly one of the two GreasedRegions), and andNot() (which can be considered the "subtract another region from me" method). There are 8-way (Chebyshev distance) variants on all of the spatial methods, and methods without "8way" in the name are either 4-way (Manhattan distance) or not affected by distance measurement. Once you have a GreasedRegion, you may want to:
You may also want to produce some 2D data from one or more GreasedRegions, as with
For efficiency, you can place one GreasedRegion into another (typically a temporary value that is no longer needed and can be recycled) using
Created by Tommy Ettinger on 6/24/2016.
expand()
), retract()
), fringe()
), surface()
, and flood(GreasedRegion)
,
and slightly faster on others, like and(GreasedRegion)
(called intersectPacked() in CoordPacker) and
or(GreasedRegion)
(called unionPacked() in CoordPacker).
Each GreasedRegion is mutable, and instance methods typically modify that instance and return it for chaining. There are exceptions, usually where multiple GreasedRegion values are returned and the instance is not modified.
Typical usage involves constructing a GreasedRegion from some input data, like a char[][] for a map or a double[][] from DijkstraMap, and modifying it spatially with expand(), retract(), flood(), etc. It's common to mix in data from other GreasedRegions with and() (which gets the intersection of two GreasedRegions and stores it in one), or() (which is like and() but for the union), xor() (like and() but for exclusive or, finding only cells that are on in exactly one of the two GreasedRegions), and andNot() (which can be considered the "subtract another region from me" method). There are 8-way (Chebyshev distance) variants on all of the spatial methods, and methods without "8way" in the name are either 4-way (Manhattan distance) or not affected by distance measurement. Once you have a GreasedRegion, you may want to:
- get a single random point from it (use
singleRandom(IRNG)
), - get several random points from it with random sampling (use
randomPortion(IRNG, int)
), - mutate the current GreasedRegion to keep random points from it with random sampling (use
randomRegion(IRNG, int)
), - get random points that are likely to be separated (use
mixedRandomSeparated(double, int, long)
with a random long for the last parameter, orquasiRandomSeparated(double)
if you don't want a random seed), - do what any of the above "separated" methods can do, but mutate the current GreasedRegion (use
mixedRandomRegion(double, int, long)
orquasiRandomRegion(double, int)
), - get all points from it (use
asCoords()
to get a Coord array, or produce a 2D array of the contents withdecode()
ortoChars(char, char)
), - use it to modify other 2D data, such as with
mask(char[][], char)
,inverseMask(char[][], char)
,writeDoubles(double[][], double)
, orwriteIntsInto(int[][], int)
, along with variations on those.
You may also want to produce some 2D data from one or more GreasedRegions, as with
sum(GreasedRegion...)
or
toChars()
. The most effective techniques regarding GreasedRegion involve multiple methods, like getting a
few random points from an existing GreasedRegion representing floor tiles in a dungeon with
randomRegion(IRNG, int)
, then finding a random expansion of those initial points with
spill(GreasedRegion, int, IRNG)
, giving the original GreasedRegion of floor tiles as the first argument.
This could be used to position puddles of water or toxic waste in a dungeon level, while still keeping the starting
points and finished points within the boundaries of valid (floor) cells. If you wanted to place something like mold
that can be on floors or on cells immediately adjacent to floors (like walls), you could call expand()
on
the floor tiles before calling spill, allowing the spill to spread onto non-floor cells that are next to floors.
For efficiency, you can place one GreasedRegion into another (typically a temporary value that is no longer needed and can be recycled) using
remake(GreasedRegion)
, or give the information that would normally be used to
construct a fresh GreasedRegion to an existing one of the same dimensions with refill(boolean[][])
or any
of the overloads of refill(). These re-methods don't do as much work as a constructor does if the width and height
of their argument are identical to their current width and height, and don't create more garbage for the GC.
Created by Tommy Ettinger on 6/24/2016.
- See Also:
- Serialized Form
-
Nested Class Summary
Nested Classes Modifier and Type Class Description class
GreasedRegion.GRIterator
Nested classes/interfaces inherited from interface squidpony.squidgrid.zone.Zone
Zone.Helper, Zone.Skeleton
-
Field Summary
-
Constructor Summary
Constructors Constructor Description GreasedRegion()
Constructs an empty 64x64 GreasedRegion.GreasedRegion(boolean[][] bits)
Constructs a GreasedRegion with the given rectangular boolean array, with width of bits.length and height of bits[0].length, any value of true considered "on", and any value of false considered "off."GreasedRegion(boolean[] bits, int width, int height)
Constructs a GreasedRegion with the given 1D boolean array, with the given width and height, where an [x][y] position is obtained from bits given an index n with x = n / height, y = n % height, any value of true considered "on", and any value of false considered "off."GreasedRegion(byte[][] map, int lower, int upper)
Constructs this GreasedRegion using a byte[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.GreasedRegion(char[][] map, char yes)
Constructs a GreasedRegion with the given rectangular char array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."GreasedRegion(char[][] map, char[] yes)
Constructs a GreasedRegion with the given rectangular char array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."GreasedRegion(double[][] map, double upperBound)
Constructs this GreasedRegion using a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states: an "on" state for values less than or equal to upperBound (inclusive), and an "off" state for anything else.GreasedRegion(double[][] map, double lowerBound, double upperBound)
Constructs this GreasedRegion using a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else.GreasedRegion(double[][] map, double lowerBound, double upperBound, int scale)
Constructs this GreasedRegion using a double[][] that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else.GreasedRegion(int[][] map, int yes)
Constructs a GreasedRegion with the given rectangular int array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."GreasedRegion(int[][] map, int lower, int upper)
Constructs this GreasedRegion using an int[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.GreasedRegion(int width, int height)
Constructor for an empty GreasedRegion of the given width and height.GreasedRegion(int width, int height, Iterable<Coord> points)
Constructor for a GreasedRegion that can have several "on" cells specified, and has the given width and height.GreasedRegion(int width, int height, Coord... points)
Constructor for a GreasedRegion that can have several "on" cells specified, and has the given width and height.GreasedRegion(long[] data2, int width, int height)
Primarily for internal use, this constructor copies data2 exactly into the internal long array the new GreasedRegion will use, and does not perform any validation steps to ensure that cells that would be "on" but are outside the actual height of the GreasedRegion are actually removed (this only matters if height is not a multiple of 64).GreasedRegion(long[] data2, int dataWidth, int dataHeight, int width, int height)
Primarily for internal use, this constructor copies data2 into the internal long array the new GreasedRegion will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for the constructed GreasedRegion.GreasedRegion(short[][] map, int lower, int upper)
Constructs this GreasedRegion using a short[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.GreasedRegion(String[] map, char yes)
Weird constructor that takes a String array, _as it would be printed_, so each String is a row and indexing would be done with y, x instead of the normal x, y.GreasedRegion(Coord single, int width, int height)
Constructor for a GreasedRegion that contains a single "on" cell, and has the given width and height.GreasedRegion(GreasedRegion other)
Copy constructor that takes another GreasedRegion and copies all of its data into this new one.GreasedRegion(IRNG random, int width, int height)
Constructor for a random GreasedRegion of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off.GreasedRegion(RandomnessSource random, double fraction, int width, int height)
Constructor for a random GreasedRegion of the given width and height, trying to set the given fraction of cells to on.GreasedRegion(RandomnessSource random, int width, int height)
Constructor for a random GreasedRegion of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off. -
Method Summary
Modifier and Type Method Description boolean
add(Coord coord)
boolean
addAll(Collection<? extends Coord> c)
GreasedRegion
allOn()
Sets all cells in this to "on."GreasedRegion
alterBounds(int widthChange, int heightChange)
Changes the width and/or height of this GreasedRegion, enlarging or shrinking starting at the edges wherex == width - 1
andy == height - 1
.GreasedRegion
and(GreasedRegion other)
Intersection of two GreasedRegions, assigning the result into this GreasedRegion.GreasedRegion
andNot(GreasedRegion other)
Difference of two GreasedRegions, assigning the result into this GreasedRegion.GreasedRegion
andWrapping64(GreasedRegion other)
Intersection of two GreasedRegions, assigning the result into this GreasedRegion, with the special requirement that other must be a 64x64 area, and the special property that other will be considered tiled to cover all of the area of this GreasedRegion.static Collection<GreasedRegion>
appendContaining(Collection<GreasedRegion> into, int x, int y, Collection<GreasedRegion> packed)
Tries to look up the position x,y in each GreasedRegion in packed; each GreasedRegion that contains that x,y point is appended into the Collectioninto
.static Collection<GreasedRegion>
appendContaining(Collection<GreasedRegion> into, int x, int y, GreasedRegion... packed)
Tries to look up the position x,y in each GreasedRegion in packed; each GreasedRegion that contains that x,y point is appended into the Collectioninto
.static long
approximateBits(RandomnessSource random, int bitCount)
Generates a random 64-bit long with a number of '1' bits (Hamming weight) equal on average to bitCount.Coord[]
asCoords()
Coord[]
asCoords(Coord[] points)
int[]
asEncoded()
int[]
asTightEncoded()
Coord
atFraction(double fraction)
int
atFractionTight(double fraction)
static int[][]
bitSum(GreasedRegion... regions)
Generates a 2D int array from an array or vararg of GreasedRegions, treating each cell in the nth region as the nth bit of the int at the corresponding x,y cell in the int array.void
clear()
GreasedRegion
connect()
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal line, and changes the gap cells to "on" as well.GreasedRegion
connect8way()
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.GreasedRegion
connectLines()
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.boolean
contains(int x, int y)
boolean
contains(Object o)
boolean
contains(Zone other)
Checks whether all Coords inother
are also present inthis
.boolean
contains(Coord c)
Checks ifc
is present in this GreasedRegion.boolean
containsAll(Collection<?> c)
GreasedRegion
copy()
Simple method that returns a newly-allocated copy of this GreasedRegion; modifications to one won't change the other, and this method returns the copy while leaving the original unchanged.GreasedRegion
copyRotated(int turns)
Makes a copy of this GreasedRegion that has been rotated 90 degreesturns
times.boolean[][]
decode()
Returns this GreasedRegion's data as a 2D boolean array, [width][height] in size, with on treated as true and off treated as false.static GreasedRegion
decompress(String compressed)
Decompresses a String returned bytoCompressedString()
, returning a new GreasedRegion with identical width, height, and contents to the GreasedRegion before compression.static GreasedRegion
deserializeFromString(String s)
GreasedRegion
deteriorate(RandomnessSource random, double preservation)
Randomly removes points from a GreasedRegion, with preservation as a fraction between 1.0 (keep all) and 0.0 (remove all).GreasedRegion
deteriorate(RandomnessSource rng, int preservation)
Randomly removes points from a GreasedRegion, with larger values for preservation keeping more of the existing shape intact.static double[][]
dijkstraScan(char[][] map, Coord... goals)
Discouraged from active use; slower thanDijkstraMap
and has less features.static double[][]
dijkstraScan8way(char[][] map, Coord... goals)
Discouraged from active use; slower thanDijkstraMap
and has less features.GreasedRegion
disperse()
Removes "on" cells that are orthogonally adjacent to other "on" cells, keeping at least one cell in a group "on." Uses a "checkerboard" pattern to determine which cells to turn off, with all cells that would be black on a checkerboard turned off and all others kept as-is.GreasedRegion
disperse8way()
Removes "on" cells that are 8-way adjacent to other "on" cells, keeping at least one cell in a group "on." Uses a "grid-like" pattern to determine which cells to turn off, with all cells with even x and even y kept as-is but all other cells (with either or both odd x or odd y) turned off.static int
disperseBits(int n)
Narrow-purpose; takes an int that represents a distance down the Z-order curve and moves its bits around so that its x component is stored in the bottom 16 bits (use(n & 0xffff)
to obtain) and its y component is stored in the upper 16 bits (use(n >>> 16)
to obtain).GreasedRegion
disperseRandom(RandomnessSource random)
Removes "on" cells that are nearby other "on" cells, with a random factor to which bits are actually turned off that still ensures exactly half of the bits are kept as-is (the one exception is when height is an odd number, which makes the bottom row slightly random).GreasedRegion
empty()
Equivalent toclear()
, setting all cells to "off," but also returns this for chaining.boolean
equals(Object o)
GreasedRegion
expand()
Takes the "on" cells in this GreasedRegion and expands them by one cell in the 4 orthogonal directions, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).GreasedRegion
expand(int amount)
Takes the "on" cells in this GreasedRegion and expands them by amount cells in the 4 orthogonal directions, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).GreasedRegion
expand8way()
GreasedRegion
expand8way(int amount)
Expands this Zone in the four cardinal and four diagonal directions, performing the expansion consecutivelydistance
times.GreasedRegion[]
expandSeries(int amount)
Takes the "on" cells in this GreasedRegion and produces amount GreasedRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous GreasedRegion, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).GreasedRegion[]
expandSeries8way(int amount)
ArrayList<GreasedRegion>
expandSeriesToLimit()
ArrayList<GreasedRegion>
expandSeriesToLimit8way()
GreasedRegion
extend()
Gets a new Zone that contains all the Coords inthis
plus all neighboring Coords, which can be orthogonally or diagonally adjacent to any Coord this has in it.GreasedRegion
fill(boolean contents)
Sets all cells in this to "on" if contents is true, or "off" if contents is false.Coord
first()
Gets the first Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty.int
firstTight()
Coord
fit(double xFraction, double yFraction)
int[][]
fit(int[][] basis, int defaultValue)
GreasedRegion
flip(boolean leftRight, boolean upDown)
GreasedRegion
flood(GreasedRegion bounds)
Likeexpand()
, but limits expansion to the "on" cells ofbounds
.GreasedRegion
flood(GreasedRegion bounds, int amount)
Likeexpand(int)
, but limits expansion to the "on" cells ofbounds
.GreasedRegion
flood8way(GreasedRegion bounds)
Likeexpand8way()
, but limits expansion to the "on" cells ofbounds
.GreasedRegion
flood8way(GreasedRegion bounds, int amount)
Likeexpand8way(int)
, but limits expansion to the "on" cells ofbounds
.GreasedRegion[]
floodSeries(GreasedRegion bounds, int amount)
Repeatedly callsflood(GreasedRegion)
amount
times and returns the intermediate steps in a GreasedRegion array of sizeamount
.GreasedRegion[]
floodSeries8way(GreasedRegion bounds, int amount)
Repeatedly callsflood8way(GreasedRegion)
amount
times and returns the intermediate steps in a GreasedRegion array of sizeamount
.ArrayList<GreasedRegion>
floodSeriesToLimit(GreasedRegion bounds)
Repeatedly generates new GreasedRegions, each one cell expanded in 4 directions from the previous GreasedRegion and staying inside the "on" cells ofbounds
, until it can't expand any more.ArrayList<GreasedRegion>
floodSeriesToLimit8way(GreasedRegion bounds)
Repeatedly generates new GreasedRegions, each one cell expanded in 8 directions from the previous GreasedRegion and staying inside the "on" cells ofbounds
, until it can't expand any more.GreasedRegion
fray(double fractionKept)
Likeretract()
, this removes the "on" cells that are 4-way-adjacent to any "off" cell, but unlike that method it keeps a fraction of those surface cells, quasi-randomly selecting them.GreasedRegion
fringe()
Takes the "on" cells in this GreasedRegion and expands them by one cell in the 4 orthogonal directions, producing a diamoond shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (orthogonal-only) of an "on" cell.GreasedRegion
fringe(int amount)
Takes the "on" cells in this GreasedRegion and expands them by amount cells in the 4 orthogonal directions (iteratively, producing a diamond shape), then removes the original area before expansion, producing only the cells that were "off" in this and within amount cells (orthogonal-only) of an "on" cell.GreasedRegion
fringe8way()
GreasedRegion
fringe8way(int amount)
GreasedRegion[]
fringeSeries(int amount)
Takes the "on" cells in this GreasedRegion and produces amount GreasedRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous GreasedRegion, making each "on" cell take up a diamond- shaped area.GreasedRegion[]
fringeSeries8way(int amount)
ArrayList<GreasedRegion>
fringeSeriesToLimit()
ArrayList<GreasedRegion>
fringeSeriesToLimit8way()
List<Coord>
getAll()
double
getDiagonal()
Gets the diagonal distance from the point combining the lowest x-value present in this GreasedRegion with the lowest y-value in this, to the point combining the highest x-value and the highest y-value.GreasedRegion
getExternalBorder()
Gets a Collection of Coord values that are not in this GreasedRegion, but are adjacent to it, either orthogonally or diagonally.int
getHeight()
Gets the distance between the minimum y-value contained in this GreasedRegion and the maximum y-value in it.GreasedRegion
getInternalBorder()
int
getWidth()
Gets the distance between the minimum x-value contained in this GreasedRegion and the maximum x-value in it.long
hash64()
long
hash64(long seed)
Computes a 64-bit hash code of this GreasedRegion given a 64-bit seed; even if given two very similar seeds, this should produce very different hash codes for the same GreasedRegion.int
hashCode()
GreasedRegion
insert(int tight)
Sets the given cell, "tightly" encoded for a specific width/height as byasTightEncoded()
, to "on".GreasedRegion
insert(int x, int y)
Sets the cell at x,y to "on".GreasedRegion
insert(int x, int y, GreasedRegion other)
Takes another GreasedRegion, called other, with potentially different size and inserts its "on" cells into thi GreasedRegion at the given x,y offset, allowing negative x and/or y to put only part of other in this.GreasedRegion
insert(Coord point)
Sets the cell at point to "on".GreasedRegion
insertCircle(Coord center, int radius)
GreasedRegion
insertRectangle(int startX, int startY, int rectangleWidth, int rectangleHeight)
GreasedRegion
insertSeveral(int[] points)
GreasedRegion
insertSeveral(Iterable<Coord> points)
GreasedRegion
insertSeveral(Coord... points)
GreasedRegion
insertTranslation(int x, int y)
Adds to this GreasedRegion with a moved set of its own "on" cells, moved to the given x and y offset.static int
interleaveBits(int x, int y)
Narrow-purpose; takes an x and a y value, each between 0 and 65535 inclusive, and interleaves their bits so the least significant bit and every other bit after it are filled with the bits of x, while the second-least-significant bit and every other bit after that are filled with the bits of y.boolean
intersects(GreasedRegion other)
Returns true if any cell is "on" in both this GreasedRegion and in other; returns false otherwise.boolean
intersectsWith(Zone other)
char[][]
intoChars(char[][] chars, char on)
Fills this GreasedRegion's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteron
and "off" cells left as-is.char[][]
intoChars(char[][] chars, char on, char off)
Fills this GreasedRegion's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteron
and "off" cells with the parameteroff
.char[][]
inverseMask(char[][] map, char toWrite)
Returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the char toWrite.boolean
isEmpty()
Iterator<Coord>
iterator()
GreasedRegion
largestPart()
Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this GreasedRegion.GreasedRegion
largestPart8way()
Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this GreasedRegion.Coord
last()
Gets the last Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty.int
lastTight()
char[][]
mask(char[][] map, char filler)
Returns a copy of map where if a cell is "on" in this GreasedRegion, this keeps the value in map intact, and where a cell is "off", it instead writes the char filler.short[][]
mask(short[][] map, short filler)
Returns a copy of map where if a cell is "on" in this GreasedRegion, this keeps the value in map intact, and where a cell is "off", it instead writes the short filler.GreasedRegion
mirrorY()
Returns a new GreasedRegion that has been mirrored along the rightmost edge, parallel to the y-axis.GreasedRegion
mixedRandomRegion(double fraction)
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
mixedRandomRegion(double fraction, int limit)
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
mixedRandomRegion(double fraction, int limit, long seed)
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.Coord[]
mixedRandomSeparated(double fraction)
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
mixedRandomSeparated(double fraction, int limit)
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
mixedRandomSeparated(double fraction, int limit, long seed)
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
mixedRandomSeparatedAlt(double fraction, int limit, long seed)
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
neighborDown()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards when this is called.GreasedRegion
neighborDownLeft()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards and to the left when this is called.GreasedRegion
neighborDownRight()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards and to the right when this is called.GreasedRegion
neighborLeft()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor to the left when this is called.GreasedRegion
neighborRight()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor to the right when this is called.GreasedRegion
neighborUp()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards when this is called.GreasedRegion
neighborUpLeft()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards and to the left when this is called.GreasedRegion
neighborUpRight()
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards and to the right when this is called.GreasedRegion
not()
Negates this GreasedRegion, turning "on" to "off" and "off" to "on."GreasedRegion
notAnd(GreasedRegion other)
Like andNot, but subtracts this GreasedRegion from other and stores the result in this GreasedRegion, without mutating other.Coord
nth(int index)
Coord
nthZCurve(int index)
Likenth(int)
, this gets the Coord at a given index along a path through the GreasedRegion, but unlike nth(), this traverses the path in a zig-zag pattern called the Z-Order Curve.int
nthZCurveTight(int index)
Likenth(int)
, this finds a given index along a path through the GreasedRegion, but unlike nth(), this traverses the path in a zig-zag pattern called the Z-Order Curve, and unlikenthZCurve(int)
, this does not return a Coord and instead produces a "tight"-encoded int.static GreasedRegion
of(int width, int height, long... data)
Constructs a GreasedRegion using a vararg for data.GreasedRegion
or(GreasedRegion other)
Union of two GreasedRegions, assigning the result into this GreasedRegion.void
perceptualHashQuick(long[] into, int[] working)
Calculates a perceptual hash for this GreasedRegion using a method that is only precise for some sizes of GreasedRegion; it writes a result to into, and uses working as a temporary buffer.GreasedRegion
quasiRandomRegion(double fraction)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
quasiRandomRegion(double fraction, int limit)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.Coord[]
quasiRandomSeparated(double fraction)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
quasiRandomSeparated(double fraction, int limit)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.static long
randomInterleave(RandomnessSource random)
Gets a somewhat-random long with exactly 32 bits set; in each pair of bits starting at bit 0 and bit 1, then bit 2 and bit 3, up to bit 62 and bit 3, one bit will be 1 and one bit will be 0 in each pair.Coord[]
randomPortion(IRNG rng, int size)
GreasedRegion
randomRegion(IRNG rng, int size)
GreasedRegion
randomScatter(IRNG rng, int minimumDistance)
Modifies this GreasedRegion so it contains a random subset of its previous contents, choosing cells so that the distance between any two "on" cells is at leastminimumDistance
, with at least one cell as "on" if any were "on" in this originally.GreasedRegion
randomScatter(IRNG rng, int minimumDistance, int limit)
Modifies this GreasedRegion so it contains a random subset of its previous contents, choosing cells so that the distance between any two "on" cells is at leastminimumDistance
, with at least one cell as "on" if any were "on" in this originally.Coord[]
randomSeparated(double fraction, IRNG rng)
Don't use this in new code; prefermixedRandomSeparated(double, int, long)
with a random long as the last parameter.Coord[]
randomSeparated(double fraction, IRNG rng, int limit)
Don't use this in new code; prefermixedRandomSeparated(double, int, long)
with a random long as the last parameter.double
rateDensity()
double
rateRegularity()
GreasedRegion
refill(boolean[][] map)
Reassigns this GreasedRegion with the given rectangular boolean array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(boolean[] bits, int width, int height)
Reassigns this GreasedRegion with the given 1D boolean array, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, where an [x][y] position is obtained from bits given an index n with x = n / height, y = n % height, any value of true considered "on", and any value of false considered "off."GreasedRegion
refill(byte[][] map, int lower, int upper)
Reassigns this GreasedRegion with the given rectangular byte array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(char[][] map, char yes)
Reassigns this GreasedRegion with the given rectangular char array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(char[][] map, char[] yes)
Reassigns this GreasedRegion with the given rectangular char array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(double[][] map, double upperBound)
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(double[][] map, double lower, double upper)
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(double[][] map, double lowerBound, double upperBound, int scale)
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) ifthis.width == map.length * scale && this.height == map[0].length * scale
.GreasedRegion
refill(int[][] map, int yes)
Reassigns this GreasedRegion with the given rectangular int array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(int[][] map, int lower, int upper)
Reassigns this GreasedRegion with the given rectangular int array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(long[] data2, int dataWidth, int dataHeight, int width, int height)
Primarily for internal use, this method copies data2 into the internal long array the new GreasedRegion will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for this GreasedRegion, potentially re-allocating the internal data this uses if width and/or height are different from what they were.GreasedRegion
refill(short[][] map, int lower, int upper)
Reassigns this GreasedRegion with the given rectangular short array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.GreasedRegion
refill(String[] map, char yes)
Weird refill method that takes a String array, _as it would be printed_, so each String is a row and indexing would be done with y, x instead of the normal x, y.GreasedRegion
refill(IRNG random, int width, int height)
Reassigns this GreasedRegion by filling it with random values from random, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, and typically assigning approximately half of the cells in this to "on" and the rest to off.GreasedRegion
refill(RandomnessSource random, double fraction, int width, int height)
Reassigns this GreasedRegion randomly, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, while trying to set the given fraction of cells to on.GreasedRegion
refill(RandomnessSource random, int width, int height)
Reassigns this GreasedRegion by filling it with random values from random, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, and typically assigning approximately half of the cells in this to "on" and the rest to off.GreasedRegion
remake(GreasedRegion other)
A useful method for efficiency, remake() reassigns this GreasedRegion to have its contents replaced by other.GreasedRegion
remove(int x, int y)
GreasedRegion
remove(int x, int y, GreasedRegion other)
Takes another GreasedRegion, called other, with potentially different size and removes its "on" cells from this GreasedRegion at the given x,y offset, allowing negative x and/or y to remove only part of other in this.boolean
remove(Object o)
GreasedRegion
remove(Coord point)
boolean
removeAll(Collection<?> c)
GreasedRegion
removeCircle(Coord center, int radius)
GreasedRegion
removeCorners()
Where a cell is "on" but forms a right-angle with exactly two orthogonally-adjacent "on" cells and exactly two orthogonally-adjacent "off" cells, this turns each of those cells "off." This won't affect east-west lines of flat "on" cells, nor north-south lines.GreasedRegion
removeEdges()
Turns all cells that are adjacent to the boundaries of the GreasedRegion to "off".GreasedRegion
removeIsolated()
GreasedRegion
removeRectangle(int startX, int startY, int rectangleWidth, int rectangleHeight)
Removes all "on" cells from (startX, startY) inclusive to (startX+rectangleWidth, startY+rectangleHeight) exclusive, removing a total width of rectangleWidth and a total height of rectangleHeight in cells.GreasedRegion
removeSeveral(Iterable<Coord> points)
GreasedRegion
removeSeveral(Coord... points)
GreasedRegion
resizeAndEmpty(int width, int height)
If this GreasedRegion has the same width and height passed as parameters, this acts the same asempty()
, makes no allocations, and returns this GreasedRegion with its contents all "off"; otherwise, this does allocate a differently-sized amount of internal data to match the new width and height, sets the fields to all match the new width and height, and returns this GreasedRegion with its new width and height, with all contents "off".boolean
retainAll(Collection<?> c)
GreasedRegion
retract()
Takes the "on" cells in this GreasedRegion and retracts them by one cell in the 4 orthogonal directions, making each "on" cell that was orthogonally adjacent to an "off" cell into an "off" cell.GreasedRegion
retract(int amount)
Takes the "on" cells in this GreasedRegion and retracts them by one cell in the 4 orthogonal directions, doing this iteeratively amount times, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.GreasedRegion
retract8way()
GreasedRegion
retract8way(int amount)
GreasedRegion[]
retractSeries(int amount)
GreasedRegion[]
retractSeries8way(int amount)
ArrayList<GreasedRegion>
retractSeriesToLimit()
ArrayList<GreasedRegion>
retractSeriesToLimit8way()
Coord[]
separatedBlue(double fraction)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
separatedBlue(double fraction, int limit)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
separatedPortion(double fraction)
Don't use this in new code; prefermixedRandomSeparated(double)
,quasiRandomSeparated(double)
, orseparatedZCurve(double)
.GreasedRegion
separatedRegionBlue(double fraction)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
separatedRegionBlue(double fraction, int limit)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
separatedRegionZCurve(double fraction)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.GreasedRegion
separatedRegionZCurve(double fraction, int limit)
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this.Coord[]
separatedZCurve(double fraction)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.Coord[]
separatedZCurve(double fraction, int limit)
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this.String
serializeToString()
GreasedRegion
set(boolean value, int x, int y)
Sets the cell at x,y to on if value is true or off if value is false.GreasedRegion
set(boolean value, Coord point)
Sets the cell at point to on if value is true or off if value is false.StringBuilder
show(char on, char off)
Returns this GreasedRegion's data as a StringBuilder, with each row made of the parameter on for "on" cells and the parameter off for "off" cells, separated by newlines, with no trailing newline at the end.Coord
singleRandom(IRNG rng)
Gets a single random Coord from the "on" positions in this GreasedRegion, or the Coord (-1,-1) if this is empty.int
singleRandomTight(IRNG rng)
int
size()
GreasedRegion
spill(GreasedRegion bounds, int volume, IRNG rng)
A randomized flood-fill that modifies this GreasedRegion so it randomly adds adjacent cells while staying inside the "on" cells ofbounds
, untilsize()
is equal tovolume
or there are no more cells this can expand into.ArrayList<GreasedRegion>
split()
If this GreasedRegion stores 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 GreasedRegion, with one GreasedRegion per isolated area.ArrayList<GreasedRegion>
split8way()
If this GreasedRegion stores multiple unconnected "on" areas, this finds each isolated area (areas that are only adjacent diagonally are considered one area with this) and returns it as an element in an ArrayList of GreasedRegion, with one GreasedRegion per isolated area.static int[][]
sum(List<GreasedRegion> regions)
Generates a 2D int array from a List of GreasedRegions, starting at all 0 and adding 1 to the int at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.static int[][]
sum(GreasedRegion... regions)
Generates a 2D int array from an array or vararg of GreasedRegions, starting at all 0 and adding 1 to the int at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.static double[][]
sumDouble(List<GreasedRegion> regions)
Generates a 2D double array from a List of GreasedRegions, starting at all 0 and adding 1 to the double at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.static double[][]
sumDouble(GreasedRegion... regions)
Generates a 2D double array from an array or vararg of GreasedRegions, starting at all 0 and adding 1 to the double at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.static int[][]
sumInto(int[][] existing, GreasedRegion... regions)
Adds to an existing 2D int array with an array or vararg of GreasedRegions, adding 1 to the int in existing at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can increase the value in existing by any number between 0 and 16 in a cell.static double[][]
sumIntoDouble(double[][] existing, GreasedRegion... regions)
Adds to an existing 2D double array with an array or vararg of GreasedRegions, adding 1 to the double in existing at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can increase the value in existing by any number between 0 and 16 in a cell.static int[][]
sumWeighted(GreasedRegion[] regions, int[] weights)
Generates a 2D int array from an array of GreasedRegions and an array of weights, starting the 2D result at all 0 and, for every GreasedRegion that has that cell as "on," adding the int in the corresponding weights array at the position of that cell.static double[][]
sumWeightedDouble(GreasedRegion[] regions, double[] weights)
Generates a 2D double array from an array of GreasedRegions and an array of weights, starting the 2D result at all 0 and, for every GreasedRegion that has that cell as "on," adding the double in the corresponding weights array at the position of that cell.GreasedRegion
surface()
GreasedRegion
surface(int amount)
GreasedRegion
surface8way()
GreasedRegion
surface8way(int amount)
GreasedRegion[]
surfaceSeries(int amount)
GreasedRegion[]
surfaceSeries8way(int amount)
ArrayList<GreasedRegion>
surfaceSeriesToLimit()
ArrayList<GreasedRegion>
surfaceSeriesToLimit8way()
GreasedRegion
thin()
Likeretract()
, this reduces the width of thick areas of this GreasedRegion, but thin() will not remove areas that would be identical in a subsequent call to retract(), such as if the area would be eliminated.GreasedRegion
thin8way()
Likeretract8way()
, this reduces the width of thick areas of this GreasedRegion, but thin8way() will not remove areas that would be identical in a subsequent call to retract8way(), such as if the area would be eliminated.GreasedRegion
thinFully()
Callsthin()
repeatedly, until the result is unchanged from the last call.GreasedRegion
thinFully8way()
Callsthin8way()
repeatedly, until the result is unchanged from the last call.Object[]
toArray()
<T> T[]
toArray(T[] a)
char[][]
toChars()
Returns this GreasedRegion's data as a 2D char array, [width][height] in size, with "on" cells filled with '.' and "off" cells with '#'.char[][]
toChars(char on, char off)
Returns this GreasedRegion's data as a 2D char array, [width][height] in size, with "on" cells filled with the char parameter on and "off" cells with the parameter off.String
toCompressedString()
Compresses this GreasedRegion into a UTF-16 String and returns the String without modifying this GreasedRegion.GreasedRegion
toggle(int x, int y)
Changes the on/off state of the cell with the given x and y, making an on cell into an off cell, or an off cell into an on cell.String
toString()
Returns a legible String representation of this that can be printed over multiple lines, with all "on" cells represented by '.' and all "off" cells by '#', in roguelike floors-on walls-off convention, separating each row by newlines (without a final trailing newline, so you could append text right after this).GreasedRegion
translate(int x, int y)
Moves the "on" cells in this GreasedRegion to the given x and y offset, removing cells that move out of bounds.GreasedRegion
translate(Coord c)
Translates a copy ofthis
by the x,y values inc
.static OrderedSet<GreasedRegion>
whichContain(int x, int y, Collection<GreasedRegion> packed)
static OrderedSet<GreasedRegion>
whichContain(int x, int y, GreasedRegion... packed)
char[][]
writeCharsInto(char[][] map, char toWrite)
LikeinverseMask(char[][], char)
, but modifiesmap
in-place and returns it.double[][]
writeDoubles(double[][] map, double toWrite)
"Inverse mask for doubles;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the double toWrite.double[][]
writeDoublesInto(double[][] map, double toWrite)
"Inverse mask for doubles;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the double toWrite.int[][]
writeInts(int[][] map, int toWrite)
"Inverse mask for ints;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the int toWrite.int[][]
writeIntsInto(int[][] map, int toWrite)
"Inverse mask for ints;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the int toWrite.int
xBound(boolean findSmallest)
GreasedRegion
xor(GreasedRegion other)
Symmetric difference (more commonly known as exclusive or, hence the name) of two GreasedRegions, assigning the result into this GreasedRegion.int
yBound(boolean findSmallest)
GreasedRegion
zoom(int x, int y)
Effectively doubles the x and y values of each cell this contains (not scaling each cell to be larger, so each "on" cell will be surrounded by "off" cells), and re-maps the positions so the given x and y in the doubled space become 0,0 in the resulting GreasedRegion (which is this, assigning to itself).Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface java.util.Collection
parallelStream, removeIf, spliterator, stream, toArray
-
Field Details
-
Constructor Details
-
GreasedRegion
public GreasedRegion()Constructs an empty 64x64 GreasedRegion. GreasedRegions are mutable, so you can add to this with insert() or insertSeveral(), among others. -
GreasedRegion
Constructs a GreasedRegion with the given rectangular boolean array, with width of bits.length and height of bits[0].length, any value of true considered "on", and any value of false considered "off."- Parameters:
bits
- a rectangular 2D boolean array where true is on and false is off
-
GreasedRegion
Constructs a GreasedRegion with the given rectangular char array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D char array where yes is on and everything else is offyes
- which char to encode as "on"
-
GreasedRegion
Constructs a GreasedRegion with the given rectangular char array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D char array where yes is on and everything else is offyes
- which char to encode as "on"
-
GreasedRegion
Weird constructor that takes a String array, _as it would be printed_, so each String is a row and indexing would be done with y, x instead of the normal x, y.- Parameters:
map
- String array (as printed, not the normal storage) where each String is a rowyes
- the char to consider "on" in the GreasedRegion
-
GreasedRegion
Constructs a GreasedRegion with the given rectangular int array, with width of map.length and height of map[0].length, any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D int array where an int == yes is on and everything else is offyes
- which int to encode as "on"
-
GreasedRegion
Constructs this GreasedRegion using an int[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- an int[][] that should have some ints between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper
-
GreasedRegion
Constructs this GreasedRegion using a byte[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a byte[][] that should have some bytes between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper
-
GreasedRegion
Constructs this GreasedRegion using a short[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a short[][] that should have some shorts between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper
-
GreasedRegion
Constructs this GreasedRegion using a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states: an "on" state for values less than or equal to upperBound (inclusive), and an "off" state for anything else.- Parameters:
map
- a double[][] that probably relates in some way to DijkstraMap.upperBound
- upper inclusive; any double greater than this will be off, any others will be on
-
GreasedRegion
Constructs this GreasedRegion using a double[][] (typically one generated byDijkstraMap
) that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else.- 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 or equal to this this will be off, any doubles both less than this and equal to or greater than lower will be on
-
GreasedRegion
Constructs this GreasedRegion using a double[][] that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else. This variant scales the input so each "on" position in map produces a 2x2 on area if scale is 2, a 3x3 area if scale is 3, and so on.- Parameters:
map
- a double[][]; depending on scale, the GreasedRegion may have different width and heightlowerBound
- 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 or equal to this this will be off, any doubles both less than this and equal to or greater than lower will be onscale
- the size of the square of cells in this that each "on" value in map will correspond to
-
GreasedRegion
Constructs a GreasedRegion with the given 1D boolean array, with the given width and height, where an [x][y] position is obtained from bits given an index n with x = n / height, y = n % height, any value of true considered "on", and any value of false considered "off."- Parameters:
bits
- a 1D boolean array where true is on and false is offwidth
- the width of the desired GreasedRegion; width * height should equal bits.lengthheight
- the height of the desired GreasedRegion; width * height should equal bits.length
-
GreasedRegion
Constructor for an empty GreasedRegion of the given width and height. GreasedRegions are mutable, so you can add to this with insert() or insertSeveral(), among others.- Parameters:
width
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion
-
GreasedRegion
Constructor for a GreasedRegion that contains a single "on" cell, and has the given width and height. Note that to avoid confusion with the constructor that takes multiple Coord values, this takes the single "on" Coord first, while the multiple-Coord constructor takes its vararg or array of Coords last.- Parameters:
single
- the one (x,y) point to store as "on" in this GreasedRegionwidth
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion
-
GreasedRegion
Constructor for a GreasedRegion that can have several "on" cells specified, and has the given width and height. Note that to avoid confusion with the constructor that takes one Coord value, this takes the vararg or array of Coords last, while the single-Coord constructor takes its one Coord first.- Parameters:
width
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegionpoints
- an array or vararg of Coord to store as "on" in this GreasedRegion
-
GreasedRegion
Constructor for a GreasedRegion that can have several "on" cells specified, and has the given width and height. Note that to avoid confusion with the constructor that takes one Coord value, this takes the Iterable of Coords last, while the single-Coord constructor takes its one Coord first.- Parameters:
width
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegionpoints
- an array or vararg of Coord to store as "on" in this GreasedRegion
-
GreasedRegion
Constructor for a random GreasedRegion of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off. A RandomnessSource can be slightly more efficient than an RNG when you're making a lot of calls on it.- Parameters:
random
- a RandomnessSource that should have a good nextLong() method; DiverRNG is excellent but Lathe32RNG is faster on GWT (only there)width
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion
-
GreasedRegion
Constructor for a random GreasedRegion of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off. A RandomnessSource can be slightly more efficient than an RNG when you're making a lot of calls on it, so you may preferGreasedRegion(RandomnessSource, int, int)
.- Parameters:
random
- an IRNG, such as an RNG, that this will use to generate its contentswidth
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion
-
GreasedRegion
Constructor for a random GreasedRegion of the given width and height, trying to set the given fraction of cells to on. Depending on the value of fraction, this makes between 0 and 6 calls to the nextLong() method of random's internal RandomnessSource, per 64 cells of this GreasedRegion (if height is not a multiple of 64, round up to get the number of calls this makes). As such, this sacrifices the precision of the fraction to obtain significantly better speed than generating one random number per cell, although the precision is probably good enough (fraction is effectively rounded down to the nearest multiple of 0.015625, and clamped between 0.0 and 1.0). The parameterrandom
can be an object like aDiverRNG
, anRNG
backed by a well-distributed RandomnessSource like its default, DiverRNG, aGWTRNG
(especially if you target GWT, where it will perform much better than most alternatives), or any of various other RandomnessSource implementations that distribute bits well forRandomnessSource.nextLong()
, but should not be intentionally-biased RNGs likeDharmaRNG
orEditRNG
, nor double-based QRNGs likeVanDerCorputQRNG
orSobolQRNG
.- Parameters:
random
- a RandomnessSource that should produce high-quality long values, like the defaults forRNG
fraction
- between 0.0 and 1.0 (clamped), only considering a precision of 1/64.0 (0.015625) between stepswidth
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion
-
GreasedRegion
Copy constructor that takes another GreasedRegion and copies all of its data into this new one. If you find yourself frequently using this constructor and assigning it to the same variable, consider using theremake(GreasedRegion)
method on the variable instead, which will, if it has the same width and height as the other GreasedRegion, avoid creating garbage and quickly fill the variable with the other's contents.- Parameters:
other
- another GreasedRegion that will be copied into this new GreasedRegion- See Also:
for a convenience method that just uses this constructor
-
GreasedRegion
Primarily for internal use, this constructor copies data2 exactly into the internal long array the new GreasedRegion will use, and does not perform any validation steps to ensure that cells that would be "on" but are outside the actual height of the GreasedRegion are actually removed (this only matters if height is not a multiple of 64).- Parameters:
data2
- a long array that is typically from another GreasedRegion, and would be hard to make otherwisewidth
- the width of the GreasedRegion to constructheight
- the height of the GreasedRegion to construct
-
GreasedRegion
Primarily for internal use, this constructor copies data2 into the internal long array the new GreasedRegion will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for the constructed GreasedRegion. This will truncate data2 on width, height, or both if width or height is smaller than dataWidth or dataHeight. It will fill extra space with all "off" if width or height is larger than dataWidth or dataHeight. It will interpret data2 as the same 2D shape regardless of the width or height it is being assigned to, and data2 will not be reshaped by truncation.- Parameters:
data2
- a long array that is typically from another GreasedRegion, and would be hard to make otherwisedataWidth
- the width to interpret data2 as havingdataHeight
- the height to interpret data2 as havingwidth
- the width of the GreasedRegion to constructheight
- the height of the GreasedRegion to construct
-
-
Method Details
-
refill
Reassigns this GreasedRegion with the given rectangular boolean array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then any value of true in map is considered "on", and any value of false in map is considered "off."- Parameters:
map
- a rectangular 2D boolean array where true is on and false is off- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular char array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D char array where yes is on and everything else is offyes
- which char to encode as "on"- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular char array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D char array where yes is on and everything else is offyes
- which char to encode as "on"- Returns:
- this for chaining
-
refill
Weird refill method that takes a String array, _as it would be printed_, so each String is a row and indexing would be done with y, x instead of the normal x, y.- Parameters:
map
- String array (as printed, not the normal storage) where each String is a rowyes
- the char to consider "on" in the GreasedRegion- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular int array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then any value that equals yes is considered "on", and any other value considered "off."- Parameters:
map
- a rectangular 2D int array where an int == yes is on and everything else is offyes
- which int to encode as "on"- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular int array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then cells are treated as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a rectangular 2D int array that should have some values between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular byte array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then cells are treated as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a rectangular 2D byte array that should have some values between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular short array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then cells are treated as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a rectangular 2D short array that should have some values between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then cells are treated as on if they are less than or equal to upperBound, or off otherwise.- Parameters:
map
- a rectangular 2D double array that should usually have some values less than or equal to upperBoundupperBound
- upper bound, inclusive; all on cells will have values in map that are less than or equal to this- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length. The current values stored in this are always cleared, then cells are treated as on if they are greater than or equal to lower and less than upper, or off otherwise.- Parameters:
map
- a rectangular 2D double array that should have some values between lower and upperlower
- lower bound, inclusive; all on cells will have values in map that are at least equal to lowerupper
- upper bound, exclusive; all on cells will have values in map that are less than upper- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given rectangular double array, reusing the current data storage (without extra allocations) ifthis.width == map.length * scale && this.height == map[0].length * scale
. The current values stored in this are always cleared, then cells are treated as on if they are greater than or equal to lower and less than upper, or off otherwise, before considering scaling. This variant scales the input so each "on" position in map produces a 2x2 on area if scale is 2, a 3x3 area if scale is 3, and so on.- Parameters:
map
- a double[][]; depending on scale, the GreasedRegion may have different width and heightlowerBound
- 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 or equal to this this will be off, any doubles both less than this and equal to or greater than lower will be onscale
- the size of the square of cells in this that each "on" value in map will correspond to- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion with the given 1D boolean array, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, where an [x][y] position is obtained from bits given an index n with x = n / height, y = n % height, any value of true considered "on", and any value of false considered "off."- Parameters:
bits
- a 1D boolean array where true is on and false is offwidth
- the width of the desired GreasedRegion; width * height should equal bits.lengthheight
- the height of the desired GreasedRegion; width * height should equal bits.length- Returns:
- this for chaining
-
resizeAndEmpty
If this GreasedRegion has the same width and height passed as parameters, this acts the same asempty()
, makes no allocations, and returns this GreasedRegion with its contents all "off"; otherwise, this does allocate a differently-sized amount of internal data to match the new width and height, sets the fields to all match the new width and height, and returns this GreasedRegion with its new width and height, with all contents "off". This is meant for cases where a GreasedRegion may be reused effectively, but its size may not always be the same.- Parameters:
width
- the width to potentially resize this GreasedRegion toheight
- the height to potentially resize this GreasedRegion to- Returns:
- this GreasedRegion, always with all contents "off", and with the height and width set.
-
refill
Reassigns this GreasedRegion by filling it with random values from random, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, and typically assigning approximately half of the cells in this to "on" and the rest to off. A RandomnessSource can be slightly more efficient than an RNG when you're making a lot of calls on it.- Parameters:
random
- a RandomnessSource that should have a good nextLong() method; DiverRNG is excellent but Lathe32RNG is faster on GWT (only there)width
- the width of the desired GreasedRegionheight
- the height of the desired GreasedRegion- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion by filling it with random values from random, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, and typically assigning approximately half of the cells in this to "on" and the rest to off.- Parameters:
random
- an IRNG that should have a good nextLong() method; an RNG constructed with the default RandomnessSource will be finewidth
- the width of the desired GreasedRegionheight
- the height of the desired GreasedRegion- Returns:
- this for chaining
-
refill
Reassigns this GreasedRegion randomly, reusing the current data storage (without extra allocations) if this.width == width and this.height == height, while trying to set the given fraction of cells to on. Depending on the value of fraction, this makes between 0 and 6 calls to the nextLong() method of random's internal RandomnessSource, per 64 cells of this GreasedRegion (if height is not a multiple of 64, round up to get the number of calls this makes). As such, this sacrifices the precision of the fraction to obtain significantly better speed than generating one random number per cell, although the precision is probably good enough (fraction is effectively rounded down to the nearest multiple of 0.015625, and clamped between 0.0 and 1.0). The parameterrandom
can be an object like aDiverRNG
, anRNG
backed by a well-distributed RandomnessSource like its default, DiverRNG, aGWTRNG
(especially if you target GWT, where it will perform much better than most alternatives), or any of various other RandomnessSource implementations that distribute bits well forRandomnessSource.nextLong()
, but should not be intentionally-biased RNGs likeDharmaRNG
orEditRNG
, nor double-based QRNGs likeVanDerCorputQRNG
orSobolQRNG
.- Parameters:
random
- a RandomnessSource that should produce high-quality long values, like the defaults forRNG
fraction
- between 0.0 and 1.0 (clamped), only considering a precision of 1/64.0 (0.015625) between stepswidth
- the maximum width for the GreasedRegionheight
- the maximum height for the GreasedRegion- Returns:
- this for chaining
-
refill
Primarily for internal use, this method copies data2 into the internal long array the new GreasedRegion will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for this GreasedRegion, potentially re-allocating the internal data this uses if width and/or height are different from what they were. This will truncate data2 on width, height, or both if width or height is smaller than dataWidth or dataHeight. It will fill extra space with all "off" if width or height is larger than dataWidth or dataHeight. It will interpret data2 as the same 2D shape regardless of the width or height it is being assigned to, and data2 will not be reshaped by truncation.- Parameters:
data2
- a long array that is typically from another GreasedRegion, and would be hard to make otherwisedataWidth
- the width to interpret data2 as havingdataHeight
- the height to interpret data2 as havingwidth
- the width to set this GreasedRegion to haveheight
- the height to set this GreasedRegion to have
-
remake
A useful method for efficiency, remake() reassigns this GreasedRegion to have its contents replaced by other. If other and this GreasedRegion have identical width and height, this is very efficient and performs no additional allocations, simply replacing the cell data in this with the cell data from other. If width and height are not both equal between this and other, this does allocate a new data array, but still reassigns this GreasedRegion in-place and acts similarly to when width and height are both equal (it just uses some more memory).
Using remake() or the similar refill() methods in chains of operations on multiple GreasedRegions can be key to maintaining good performance and memory usage. You often can recycle a no-longer-used GreasedRegion by assigning a GreasedRegion you want to keep to it with remake(), then mutating either the remade value or the one that was just filled into this but keeping one version around for later usage.- Parameters:
other
- another GreasedRegion to replace the data in this GreasedRegion with- Returns:
- this for chaining
-
alterBounds
Changes the width and/or height of this GreasedRegion, enlarging or shrinking starting at the edges wherex == width - 1
andy == height - 1
. There isn't an especially efficient way to expand from the other edges, but this method is able to copy data in bulk, so at least this method should be very fast. You can useinsert(int, int, GreasedRegion)
if you want to place one GreasedRegion inside another one, potentially with a different size. The space created by any enlargement starts all off; shrinking doesn't change the existing data where it isn't removed by the shrink.- Parameters:
widthChange
- the amount to change width by; can be positive, negative, or zeroheightChange
- the amount to change height by; can be positive, negative, or zero- Returns:
- this for chaining
-
copyRotated
Makes a copy of this GreasedRegion that has been rotated 90 degreesturns
times. If using y-down coordinates, then these rotations are clockwise; otherwise, they are counter-clockwise. This uses a copy because in many caseswhere the GreasedRegion has non-equal width and height, the rotated version has different dimensions, and that requires allocating most of a new GreasedRegion anyway. This GreasedRegion is never modifed as a result of this method.- Parameters:
turns
- how many times to rotate the copy (clockwise if using y-down, counterclockwise otherwise)- Returns:
- a potentially-rotated copy of this GreasedRegion
-
flip
-
set
Sets the cell at x,y to on if value is true or off if value is false. Does nothing if x,y is out of bounds.- Parameters:
value
- the value to set in the cellx
- the x-position of the celly
- the y-position of the cell- Returns:
- this for chaining
-
set
Sets the cell at point to on if value is true or off if value is false. Does nothing if point is out of bounds, or if point is null.- Parameters:
value
- the value to set in the cellpoint
- the x,y Coord of the cell to set- Returns:
- this for chaining
-
insert
Sets the cell at x,y to "on". Does nothing if x,y is out of bounds. More efficient, slightly, thanset(boolean, int, int)
if you just need to set a cell to "on".- Parameters:
x
- the x-position of the celly
- the y-position of the cell- Returns:
- this for chaining
-
insert
Sets the given cell, "tightly" encoded for a specific width/height as byasTightEncoded()
, to "on". Does nothing if the cell is out of bounds.- Parameters:
tight
- a cell tightly encoded for this GreasedRegion's width and height- Returns:
- this for chaining
-
insert
Sets the cell at point to "on". Does nothing if point is out of bounds, or if point is null. More efficient, slightly, thanset(boolean, Coord)
if you just need to set a cell to "on".- Parameters:
point
- the x,y Coord of the cell- Returns:
- this for chaining
-
insert
Takes another GreasedRegion, called other, with potentially different size and inserts its "on" cells into thi GreasedRegion at the given x,y offset, allowing negative x and/or y to put only part of other in this.
This is a rather complex method internally, but should be about as efficient as a general insert-region method can be.- Parameters:
x
- the x offset to start inserting other at; may be negativey
- the y offset to start inserting other at; may be negativeother
- the other GreasedRegion to insert- Returns:
- this for chaining
-
insertSeveral
-
insertSeveral
-
insertSeveral
-
insertRectangle
public GreasedRegion insertRectangle(int startX, int startY, int rectangleWidth, int rectangleHeight) -
insertCircle
-
remove
-
remove
-
remove
Takes another GreasedRegion, called other, with potentially different size and removes its "on" cells from this GreasedRegion at the given x,y offset, allowing negative x and/or y to remove only part of other in this.
This is a rather complex method internally, but should be about as efficient as a general remove-region method can be. The code is identical toinsert(int, int, GreasedRegion)
except that where insert only adds cells, this only removes cells. Essentially, insert() is toor(GreasedRegion)
as remove() is toandNot(GreasedRegion)
.- Parameters:
x
- the x offset to start removing other from; may be negativey
- the y offset to start removing other from; may be negativeother
- the other GreasedRegion to remove- Returns:
- this for chaining
-
removeSeveral
-
removeSeveral
-
removeRectangle
public GreasedRegion removeRectangle(int startX, int startY, int rectangleWidth, int rectangleHeight)Removes all "on" cells from (startX, startY) inclusive to (startX+rectangleWidth, startY+rectangleHeight) exclusive, removing a total width of rectangleWidth and a total height of rectangleHeight in cells.- Parameters:
startX
- left side x-coordinatestartY
- top side (or bottom if positive y is up) y-coordinaterectangleWidth
- how many cells wide the area to remove isrectangleHeight
- how many cells tal the area to remove is- Returns:
- this, after modification, for chaining
-
removeCircle
-
empty
Equivalent toclear()
, setting all cells to "off," but also returns this for chaining.- Returns:
- this for chaining
-
allOn
Sets all cells in this to "on."- Returns:
- this for chaining
-
fill
Sets all cells in this to "on" if contents is true, or "off" if contents is false.- Parameters:
contents
- true to set all cells to on, false to set all cells to off- Returns:
- this for chaining
-
removeEdges
Turns all cells that are adjacent to the boundaries of the GreasedRegion to "off".- Returns:
- this for chaining
-
copy
Simple method that returns a newly-allocated copy of this GreasedRegion; modifications to one won't change the other, and this method returns the copy while leaving the original unchanged.- Returns:
- a copy of this GreasedRegion; the copy can be changed without altering the original
-
decode
Returns this GreasedRegion's data as a 2D boolean array, [width][height] in size, with on treated as true and off treated as false.- Returns:
- a 2D boolean array that represents this GreasedRegion's data
-
intoChars
Fills this GreasedRegion's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteron
and "off" cells with the parameteroff
.- Parameters:
chars
- a 2D char array that will be modified; must not be null, nor can it contain null elementson
- the char to use for "on" cellsoff
- the char to use for "off" cells- Returns:
- a 2D char array that represents this GreasedRegion's data
-
intoChars
Fills this GreasedRegion's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteron
and "off" cells left as-is.- Parameters:
chars
- a 2D char array that will be modified; must not be null, nor can it contain null elementson
- the char to use for "on" cells- Returns:
- a 2D char array that represents the "on" cells in this GreasedRegion's data written over chars
-
toChars
Returns this GreasedRegion's data as a 2D char array, [width][height] in size, with "on" cells filled with the char parameter on and "off" cells with the parameter off.- Parameters:
on
- the char to use for "on" cellsoff
- the char to use for "off" cells- Returns:
- a 2D char array that represents this GreasedRegion's data
-
toChars
Returns this GreasedRegion's data as a 2D char array, [width][height] in size, with "on" cells filled with '.' and "off" cells with '#'.- Returns:
- a 2D char array that represents this GreasedRegion's data
-
show
Returns this GreasedRegion's data as a StringBuilder, with each row made of the parameter on for "on" cells and the parameter off for "off" cells, separated by newlines, with no trailing newline at the end.- Parameters:
on
- the char to use for "on" cellsoff
- the char to use for "off" cells- Returns:
- a StringBuilder that stores each row of this GreasedRegion as chars, with rows separated by newlines.
-
toString
Returns a legible String representation of this that can be printed over multiple lines, with all "on" cells represented by '.' and all "off" cells by '#', in roguelike floors-on walls-off convention, separating each row by newlines (without a final trailing newline, so you could append text right after this). -
mask
Returns a copy of map where if a cell is "on" in this GreasedRegion, this keeps the value in map intact, and where a cell is "off", it instead writes the char filler.- Parameters:
map
- a 2D char array that will not be modifiedfiller
- the char to use where this GreasedRegion stores an "off" cell- Returns:
- a masked copy of map
-
mask
Returns a copy of map where if a cell is "on" in this GreasedRegion, this keeps the value in map intact, and where a cell is "off", it instead writes the short filler. Meant for use with MultiSpill, but may be used anywhere you have a 2D short array.mask(char[][], char)
is more likely to be useful.- Parameters:
map
- a 2D short array that will not be modifiedfiller
- the short to use where this GreasedRegion stores an "off" cell- Returns:
- a masked copy of map
-
inverseMask
Returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the char toWrite.- Parameters:
map
- a 2D char array that will not be modifiedtoWrite
- the char to use where this GreasedRegion stores an "on" cell- Returns:
- a masked copy of map
-
writeInts
"Inverse mask for ints;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the int toWrite.- Parameters:
map
- a 2D int array that will not be modifiedtoWrite
- the int to use where this GreasedRegion stores an "on" cell- Returns:
- an altered copy of map
-
writeIntsInto
"Inverse mask for ints;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the int toWrite. Modifies map in-place, unlikewriteInts(int[][], int)
.- Parameters:
map
- a 2D int array that will be modifiedtoWrite
- the int to use where this GreasedRegion stores an "on" cell- Returns:
- map, with the changes applied; not a copy
-
writeDoubles
"Inverse mask for doubles;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the double toWrite.- Parameters:
map
- a 2D double array that will not be modifiedtoWrite
- the double to use where this GreasedRegion stores an "on" cell- Returns:
- an altered copy of map
-
writeDoublesInto
"Inverse mask for doubles;" returns a copy of map where if a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the double toWrite. Modifies map in-place, unlikewriteDoubles(double[][], double)
.- Parameters:
map
- a 2D double array that will be modifiedtoWrite
- the double to use where this GreasedRegion stores an "on" cell- Returns:
- map, with the changes applied; not a copy
-
writeCharsInto
LikeinverseMask(char[][], char)
, but modifiesmap
in-place and returns it. If a cell is "off" in this GreasedRegion, this keeps the value in map intact, and where a cell is "on", it instead writes the char toWrite. Modifies map in-place, unlikeinverseMask(char[][], char)
.- Parameters:
map
- a 2D char array that will be modifiedtoWrite
- the char to use where this GreasedRegion stores an "on" cell- Returns:
- map, with the changes applied; not a copy
-
or
Union of two GreasedRegions, assigning the result into this GreasedRegion. Any cell that is "on" in either GreasedRegion will be made "on" in this GreasedRegion.- Parameters:
other
- another GreasedRegion that will not be modified- Returns:
- this, after modification, for chaining
-
and
Intersection of two GreasedRegions, assigning the result into this GreasedRegion. Any cell that is "on" in both GreasedRegions will be kept "on" in this GreasedRegion, but all other cells will be made "off."- Parameters:
other
- another GreasedRegion that will not be modified- Returns:
- this, after modification, for chaining
-
andWrapping64
Intersection of two GreasedRegions, assigning the result into this GreasedRegion, with the special requirement that other must be a 64x64 area, and the special property that other will be considered tiled to cover all of the area of this GreasedRegion. Any cell that is "on" in both GreasedRegions (treating other as tiling) will be kept "on" in this GreasedRegion, but all other cells will be made "off."- Parameters:
other
- another GreasedRegion that will not be modified but must be 64x64 in size; will act as if it tiles- Returns:
- this, after modification, for chaining
-
andNot
Difference of two GreasedRegions, assigning the result into this GreasedRegion. Any cell that is "on" in this GreasedRegion and "off" in other will be kept "on" in this GreasedRegion, but all other cells will be made "off."- Parameters:
other
- another GreasedRegion that will not be modified- Returns:
- this, after modification, for chaining
- See Also:
notAnd is a very similar method that acts sort-of in reverse of this method
-
notAnd
Like andNot, but subtracts this GreasedRegion from other and stores the result in this GreasedRegion, without mutating other.- Parameters:
other
- another GreasedRegion that will not be modified- Returns:
- this, after modification, for chaining
- See Also:
andNot is a very similar method that acts sort-of in reverse of this method
-
xor
Symmetric difference (more commonly known as exclusive or, hence the name) of two GreasedRegions, assigning the result into this GreasedRegion. Any cell that is "on" in this and "off" in other, or "off" in this and "on" in other, will be made "on" in this; all other cells will be made "off." Useful to find cells that are "on" in exactly one of two GreasedRegions (not "on" in both, or "off" in both).- Parameters:
other
- another GreasedRegion that will not be modified- Returns:
- this, after modification, for chaining
-
not
Negates this GreasedRegion, turning "on" to "off" and "off" to "on."- Returns:
- this, after modification, for chaining
-
translate
Moves the "on" cells in this GreasedRegion to the given x and y offset, removing cells that move out of bounds.- Specified by:
translate
in interfaceZone
- Overrides:
translate
in classZone.Skeleton
- Parameters:
x
- the x offset to translate by; can be negativey
- the y offset to translate by; can be negative- Returns:
- this for chaining
-
insertTranslation
Adds to this GreasedRegion with a moved set of its own "on" cells, moved to the given x and y offset. Ignores cells that would be added out of bounds. Keeps all cells that are currently "on" unchanged.- Parameters:
x
- the x offset to translate by; can be negativey
- the y offset to translate by; can be negative- Returns:
- this for chaining
-
zoom
Effectively doubles the x and y values of each cell this contains (not scaling each cell to be larger, so each "on" cell will be surrounded by "off" cells), and re-maps the positions so the given x and y in the doubled space become 0,0 in the resulting GreasedRegion (which is this, assigning to itself).- Parameters:
x
- in the doubled coordinate space, the x position that should become 0 x in the result; can be negativey
- in the doubled coordinate space, the y position that should become 0 y in the result; can be negative- Returns:
- this for chaining
-
connect
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal line, and changes the gap cells to "on" as well.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
connect8way
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
connectLines
Takes the pairs of "on" cells in this GreasedRegion that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well. As a special case, this requires diagonals to either have no "on" cells adjacent along the perpendicular diagonal, or both cells on that perpendicular diagonal need to be "on." This is useful to counteract some less-desirable behavior ofconnect8way()
, where a right angle would always get the inner corners filled because it was considered a diagonal.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
thin
Likeretract()
, this reduces the width of thick areas of this GreasedRegion, but thin() will not remove areas that would be identical in a subsequent call to retract(), such as if the area would be eliminated. This is useful primarily for adjusting areas so they do not exceed a width of 2 cells, though their length (the longer of the two dimensions) will be unaffected by this. Especially wide, irregularly-shaped areas may have unintended appearances if you call this repeatedly or usethinFully()
; consider using this sparingly, or primarily when an area has just gotten thicker than desired.
This currently uses 4-way adjacency, but had previously used 8-way; if you want the behavior this previously had, you can usethin8way()
, but it may be a good idea to try this method as well (some of the old behavior had problems where it yielded significantly larger minimum widths in some areas).- Returns:
- this for chaining
-
thinFully
Callsthin()
repeatedly, until the result is unchanged from the last call. Consider using the idiomexpand8way().retract().thinFully()
to help change a possibly-strange appearance when the GreasedRegion this is called on touches the edges of the grid. In general, this method is likely to go too far when it tries to thin a round or irregular area, and this often results in many diagonal lines spanning the formerly-thick area.
This currently uses 4-way adjacency, but had previously used 8-way; if you want the behavior this previously had, you can usethinFully8way()
, but it may be a good idea to try this method as well (some of the old behavior had problems where it yielded significantly larger minimum widths in some areas).- Returns:
- this for chaining
-
thin8way
Likeretract8way()
, this reduces the width of thick areas of this GreasedRegion, but thin8way() will not remove areas that would be identical in a subsequent call to retract8way(), such as if the area would be eliminated. This is useful primarily for adjusting areas so they do not exceed a width of 2 cells, though their length (the longer of the two dimensions) will be unaffected by this. Especially wide, irregularly-shaped areas may have unintended appearances if you call this repeatedly or usethinFully8way()
; consider using this sparingly, or primarily when an area has just gotten thicker than desired.
This method was calledthin()
, but now that name refers to a variant that uses 4-way adjacency.- Returns:
- this for chaining
-
thinFully8way
Callsthin8way()
repeatedly, until the result is unchanged from the last call. Consider using the idiomexpand8way().retract().thinFully8way()
to help change a strange appearance when the GreasedRegion this is called on touches the edges of the grid. In general, this method is likely to go too far when it tries to thin a round or irregular area, and this often results in many diagonal lines spanning the formerly-thick area.
This method was calledthinFully()
, but now that name refers to a variant that uses 4-way adjacency.- Returns:
- this for chaining
-
disperse
Removes "on" cells that are orthogonally adjacent to other "on" cells, keeping at least one cell in a group "on." Uses a "checkerboard" pattern to determine which cells to turn off, with all cells that would be black on a checkerboard turned off and all others kept as-is.- Returns:
- this for chaining
-
disperse8way
Removes "on" cells that are 8-way adjacent to other "on" cells, keeping at least one cell in a group "on." Uses a "grid-like" pattern to determine which cells to turn off, with all cells with even x and even y kept as-is but all other cells (with either or both odd x or odd y) turned off.- Returns:
- this for chaining
-
disperseRandom
Removes "on" cells that are nearby other "on" cells, with a random factor to which bits are actually turned off that still ensures exactly half of the bits are kept as-is (the one exception is when height is an odd number, which makes the bottom row slightly random).- Parameters:
random
- the RNG used for a random factor- Returns:
- this for chaining
-
approximateBits
Generates a random 64-bit long with a number of '1' bits (Hamming weight) equal on average to bitCount. For example, calling this with a parameter of 32 will be equivalent to calling nextLong() on the given RandomnessSource, which could be anRNG
or any RandomnessSource with good 64-bit generation quality. Calling this with a parameter of 16 will have on average 16 of the 64 bits in the returned long set to '1', distributed pseudo-randomly, while a parameter of 47 will have on average 47 bits set. This can be useful for certain code that uses bits to represent data but needs a different ratio of set bits to unset bits than 1:1.
The parameterrandom
can be an object like aDiverRNG
, anRNG
backed by a well-distributed RandomnessSource like its default, DiverRNG, aGWTRNG
(especially if you target GWT, where it will perform much better than most alternatives), or any of various other RandomnessSource implementations that distribute bits well forRandomnessSource.nextLong()
, but should not be intentionally-biased RNGs likeDharmaRNG
orEditRNG
, nor double-based QRNGs likeVanDerCorputQRNG
orSobolQRNG
.- Parameters:
random
- used to determine random factors; likely to be anRNG
,DiverRNG
, orGWTRNG
bitCount
- an int, only considered if between 0 and 64, that is the average number of bits to set- Returns:
- a 64-bit long that, on average, should have bitCount bits set to 1, potentially anywhere in the long
-
randomInterleave
Gets a somewhat-random long with exactly 32 bits set; in each pair of bits starting at bit 0 and bit 1, then bit 2 and bit 3, up to bit 62 and bit 3, one bit will be 1 and one bit will be 0 in each pair.
Not exactly general-use; meant for generating data for GreasedRegion.- Returns:
- a random long with 32 "1" bits, distributed so exactly one bit is "1" for each pair of bits
-
expand
Takes the "on" cells in this GreasedRegion and expands them by one cell in the 4 orthogonal directions, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (including expand(),retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
expand
Takes the "on" cells in this GreasedRegion and expands them by amount cells in the 4 orthogonal directions, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Specified by:
expand
in interfaceMutableZone
- Parameters:
amount
- the amount to expand outward using Manhattan distance (diamond shape)- Returns:
- this for chaining
-
expandSeries
Takes the "on" cells in this GreasedRegion and produces amount GreasedRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous GreasedRegion, making each "on" cell take up a plus-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then). This returns an array of GreasedRegions with progressively greater expansions, and does not modify this GreasedRegion.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- an array of new GreasedRegions, length == amount, where each one is expanded by 1 relative to the last
-
expandSeriesToLimit
-
fringe
Takes the "on" cells in this GreasedRegion and expands them by one cell in the 4 orthogonal directions, producing a diamoond shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (orthogonal-only) of an "on" cell. This method is similar tosurface()
, but surface finds cells inside the current GreasedRegion, while fringe finds cells outside it.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time. The surface and fringe methods do allocate one temporary GreasedRegion to store the original before modification, but the others generally don't.- Returns:
- this for chaining
-
fringe
Takes the "on" cells in this GreasedRegion and expands them by amount cells in the 4 orthogonal directions (iteratively, producing a diamond shape), then removes the original area before expansion, producing only the cells that were "off" in this and within amount cells (orthogonal-only) of an "on" cell. This method is similar tosurface()
, but surface finds cells inside the current GreasedRegion, while fringe finds cells outside it.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time. The surface and fringe methods do allocate one temporary GreasedRegion to store the original before modification, but the others generally don't.- Returns:
- this for chaining
-
fringeSeries
Takes the "on" cells in this GreasedRegion and produces amount GreasedRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous GreasedRegion, making each "on" cell take up a diamond- shaped area. After producing the expansions, this removes the previous GreasedRegion from the next GreasedRegion in the array, making each "fringe" in the series have 1 "thickness," which can be useful for finding which layer of expansion a cell lies in. This returns an array of GreasedRegions with progressively greater expansions without the cells of this GreasedRegion, and does not modify this GreasedRegion.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- an array of new GreasedRegions, length == amount, where each one is a 1-depth fringe pushed further out from this
-
fringeSeriesToLimit
-
retract
Takes the "on" cells in this GreasedRegion and retracts them by one cell in the 4 orthogonal directions, making each "on" cell that was orthogonally adjacent to an "off" cell into an "off" cell.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
, retract(),fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
retract
Takes the "on" cells in this GreasedRegion and retracts them by one cell in the 4 orthogonal directions, doing this iteeratively amount times, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.
This method is very efficient due to how the class is implemented, and the various spatial increase/decrease methods (includingexpand()
,retract()
,fringe()
, andsurface()
) all perform very well by operating in bulk on up to 64 cells at a time.- Returns:
- this for chaining
-
retractSeries
-
retractSeriesToLimit
-
surface
-
surface
-
surfaceSeries
-
surfaceSeriesToLimit
-
expand8way
-
expand8way
Description copied from interface:MutableZone
Expands this Zone in the four cardinal and four diagonal directions, performing the expansion consecutivelydistance
times. Modified this Zone in-place and returns it for chaining.- Specified by:
expand8way
in interfaceMutableZone
- Parameters:
amount
- the amount to expand outward using Chebyshev distance (square shape)- Returns:
- this for chaining, after being modified in-place
-
expandSeries8way
-
expandSeriesToLimit8way
-
fringe8way
-
fringe8way
-
fringeSeries8way
-
fringeSeriesToLimit8way
-
retract8way
-
retract8way
-
retractSeries8way
-
retractSeriesToLimit8way
-
surface8way
-
surface8way
-
surfaceSeries8way
-
surfaceSeriesToLimit8way
-
flood
Likeexpand()
, but limits expansion to the "on" cells ofbounds
. Expands in all 4-way directions by one cell simultaneously, and only successfully affects the cells that are adjacent to this and are in bounds.- Parameters:
bounds
- the set of "on" cells that limits where this can expand into- Returns:
- this, after expanding, for chaining
-
flood
Likeexpand(int)
, but limits expansion to the "on" cells ofbounds
. Repeatedly expands in the 4-way directions by one cell simultaneously, and only successfully affects the cells that are adjacent to the previous expansion and are in bounds. This won't skip over gaps in bounds, even if amount is high enough that a call toexpand(int)
would reach past the gap; it will stop at the gap and only pass it if expansion takes it around.- Parameters:
bounds
- the set of "on" cells that limits where this can expand intoamount
- how far to expand this outward by, in cells- Returns:
- this, after expanding, for chaining
-
floodSeries
Repeatedly callsflood(GreasedRegion)
amount
times and returns the intermediate steps in a GreasedRegion array of sizeamount
. Doesn't modify this GreasedRegion, and doesn't return it in the array (it may return a copy of it if and only if no flood8way() calls can expand the area). If this fillsbounds
as fully as possible and still has steps left, the remaining steps are all copies of the fully-filled area.- Parameters:
bounds
- the set of "on" cells that this will attempt to fill in stepsamount
- how many steps to flood outward, and the size of the array to return- Returns:
- an array of GreasedRegion,
amount
in size, containing larger and larger expansions of this
-
floodSeriesToLimit
Repeatedly generates new GreasedRegions, each one cell expanded in 4 directions from the previous GreasedRegion and staying inside the "on" cells ofbounds
, until it can't expand any more. Returns an ArrayList of the GreasedRegion steps this generated; this list does not include this GreasedRegion (or any unmodified copy of this GreasedRegion), and this method does not modify it.- Parameters:
bounds
- the set of "on" cells that this will attempt to fill in steps- Returns:
- an ArrayList of steps from one
flood(GreasedRegion)
call to possibly many chained after it
-
flood8way
Likeexpand8way()
, but limits expansion to the "on" cells ofbounds
. Expands in all directions by one cell simultaneously, and only successfully affects the cells that are adjacent to this and are in bounds.- Parameters:
bounds
- the set of "on" cells that limits where this can expand into- Returns:
- this, after expanding, for chaining
-
flood8way
Likeexpand8way(int)
, but limits expansion to the "on" cells ofbounds
. Repeatedly expands in all directions by one cell simultaneously, and only successfully affects the cells that are adjacent to the previous expansion and are in bounds. This won't skip over gaps in bounds, even if amount is high enough that a call toexpand8way(int)
would reach past the gap; it will stop at the gap and only pass it if expansion takes it around.- Parameters:
bounds
- the set of "on" cells that limits where this can expand intoamount
- how far to expand this outward by, in cells- Returns:
- this, after expanding, for chaining
-
floodSeries8way
Repeatedly callsflood8way(GreasedRegion)
amount
times and returns the intermediate steps in a GreasedRegion array of sizeamount
. Doesn't modify this GreasedRegion, and doesn't return it in the array (it may return a copy of it if and only if no flood8way() calls can expand the area). If this fillsbounds
as fully as possible and still has steps left, the remaining steps are all copies of the fully-filled area.- Parameters:
bounds
- the set of "on" cells that this will attempt to fill in stepsamount
- how many steps to flood outward, and the size of the array to return- Returns:
- an array of GreasedRegion,
amount
in size, containing larger and larger expansions of this
-
floodSeriesToLimit8way
Repeatedly generates new GreasedRegions, each one cell expanded in 8 directions from the previous GreasedRegion and staying inside the "on" cells ofbounds
, until it can't expand any more. Returns an ArrayList of the GreasedRegion steps this generated; this list does not include this GreasedRegion (or any unmodified copy of this GreasedRegion), and this method does not modify it.- Parameters:
bounds
- the set of "on" cells that this will attempt to fill in steps- Returns:
- an ArrayList of steps from one
flood8way(GreasedRegion)
call to possibly many chained after it
-
spill
A randomized flood-fill that modifies this GreasedRegion so it randomly adds adjacent cells while staying inside the "on" cells ofbounds
, untilsize()
is equal tovolume
or there are no more cells this can expand into. This GreasedRegion acts as the initial state, and often contains just one cell before this is called. This method is useful for imitating the movement of fluids like water or smoke within some boundaries.- Parameters:
bounds
- this GreasedRegion will only expand to cells that are "on" in bounds; bounds should overlap with thisvolume
- the maximumsize()
this GreasedRegion can reach before this stops expandingrng
- a random number generator, likeRNG
orGWTRNG
- Returns:
- this, after expanding randomly, for chaining
-
removeCorners
Where a cell is "on" but forms a right-angle with exactly two orthogonally-adjacent "on" cells and exactly two orthogonally-adjacent "off" cells, this turns each of those cells "off." This won't affect east-west lines of flat "on" cells, nor north-south lines.- Returns:
- this, after removing right-angle corner "on" cells, for chaining
-
split
If this GreasedRegion stores 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 GreasedRegion, with one GreasedRegion per isolated area. Not to be confused withsplit8way()
, which considers diagonally-adjacent cells as part of one region, while this method requires cells to be orthogonally adjacent.
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 using:
GreasedRegion floors = new GreasedRegion(map, '.'), rooms = floors.copy().retract8way().flood(floors, 2), corridors = floors.copy().andNot(rooms), doors = rooms.copy().and(corridors.copy().fringe());
You can then get all rooms as separate regions withList<GreasedRegion> 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.- Returns:
- an ArrayList containing each unconnected area from packed as a GreasedRegion element
- See Also:
for a class that uses this technique without exposing GreasedRegion
-
split8way
If this GreasedRegion stores multiple unconnected "on" areas, this finds each isolated area (areas that are only adjacent diagonally are considered one area with this) and returns it as an element in an ArrayList of GreasedRegion, with one GreasedRegion per isolated area. This should not be confused withsplit()
, which is almost identical except that split() considers only orthogonal connections, while this method considers both orthogonal and diagonal connections between cells as joining an 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 using:
GreasedRegion floors = new GreasedRegion(map, '.'), rooms = floors.copy().retract8way().flood(floors, 2), corridors = floors.copy().andNot(rooms), doors = rooms.copy().and(corridors.copy().fringe());
You can then get all rooms as separate regions withList<GreasedRegion> 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.- Returns:
- an ArrayList containing each unconnected area from packed as a GreasedRegion element
- See Also:
for a class that uses this technique without exposing GreasedRegion
-
largestPart
Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this GreasedRegion. If there are multiple areas that are all equally large with no larger area, this returns the region it checks first and still is largest (first determined by the same orderingnth(int)
takes). This may return an empty GreasedRegion if there are no "on" cells, but it will never return null. Here, contiguous means adjacent on an orthogonal direction, and this doesn't consider diagonally-connected cells as contiguous unless they also have an orthogonal connection.- Returns:
- a new GreasedRegion that corresponds to the largest contiguous sub-region of "on" cells in this.
-
largestPart8way
Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this GreasedRegion. If there are multiple areas that are all equally large with no larger area, this returns the region it checks first and still is largest (first determined by the same orderingnth(int)
takes). This may return an empty GreasedRegion if there are no "on" cells, but it will never return null. Here, contiguous means adjacent on any 8-way direction, and considers cells as part of a contiguous area even if all connections but one, which can be orthogonal or diagonal, are blocked by "off" cells.- Returns:
- a new GreasedRegion that corresponds to the largest contiguous sub-region of "on" cells in this.
-
neighborUp
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards when this is called. Up is defined as negative y. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborDown
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards when this is called. Down is defined as positive y. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborLeft
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor to the left when this is called. Left is defined as negative x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborRight
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor to the right when this is called. Right is defined as positive x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborUpLeft
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards and to the left when this is called. Up is defined as negative y, left as negative x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborUpRight
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor upwards and to the right when this is called. Up is defined as negative y, right as positive x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborDownLeft
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards and to the left when this is called. Down is defined as positive y, left as negative x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
neighborDownRight
Modifies this GreasedRegion so the only cells that will be "on" have a neighbor downwards and to the right when this is called. Down is defined as positive y, right as positive x. Neighbors are "on" cells exactly one cell away. A cell can have a neighbor without itself being on; this is useful when finding the "shadow" cast away from "on" cells in one direction.- Returns:
- this, after modifications, for chaining
-
removeIsolated
-
intersects
Returns true if any cell is "on" in both this GreasedRegion and in other; returns false otherwise. For example, if (1,1) is "on" in this and (1,1) is "on" in other, this would return true, regardless of other cells.- Parameters:
other
- another GreasedRegion; its size does not have to match this GreasedRegion's size- Returns:
- true if this shares any "on" cells with other
-
whichContain
-
whichContain
public static OrderedSet<GreasedRegion> whichContain(int x, int y, Collection<GreasedRegion> packed) -
appendContaining
public static Collection<GreasedRegion> appendContaining(Collection<GreasedRegion> into, int x, int y, GreasedRegion... packed)Tries to look up the position x,y in each GreasedRegion in packed; each GreasedRegion that contains that x,y point is appended into the Collectioninto
.- Parameters:
into
- a Collection of GreasedRegion that will be modified if this succeedsx
- the x-coordinate to look upy
- the y-coordinate to look uppacked
- the array or varargs of GreasedRegion to try to look up the given position in- Returns:
into
, potentially modified
-
appendContaining
public static Collection<GreasedRegion> appendContaining(Collection<GreasedRegion> into, int x, int y, Collection<GreasedRegion> packed)Tries to look up the position x,y in each GreasedRegion in packed; each GreasedRegion that contains that x,y point is appended into the Collectioninto
.- Parameters:
into
- a Collection of GreasedRegion that will be modified if this succeedsx
- the x-coordinate to look upy
- the y-coordinate to look uppacked
- the Collection of GreasedRegion to try to look up the given position in- Returns:
into
, potentially modified
-
size
- Specified by:
size
in interfaceCollection<Coord>
- Specified by:
size
in interfaceZone
- Overrides:
size
in classZone.Skeleton
- Returns:
- The number of cells that this zone contains (the size
Zone.getAll()
).
-
fit
-
fit
-
separatedPortion
Don't use this in new code; prefermixedRandomSeparated(double)
,quasiRandomSeparated(double)
, orseparatedZCurve(double)
. This method has issues with being unable to fill the requested fraction, but the others mentioned don't. See their documentation for what all these group of methods do.- Parameters:
fraction
- between 0.0 and 1.0- Returns:
- a Coord array that may not have the full fraction used; you have been advised
-
randomSeparated
Don't use this in new code; prefermixedRandomSeparated(double, int, long)
with a random long as the last parameter. This method has issues with being unable to fill the requested fraction, but mixedRandomSeparated does not. See its documentation for what this method is supposed to do.- Parameters:
fraction
- between 0.0 and 1.0rng
- an IRNG that will be used to get a random starting point in the Sobol sequence this uses internally- Returns:
- a Coord array that may not have the full fraction used; you have been advised
-
randomSeparated
Don't use this in new code; prefermixedRandomSeparated(double, int, long)
with a random long as the last parameter. This method has issues with being unable to fill the requested fraction, but mixedRandomSeparated does not. See its documentation for what this method is supposed to do.- Parameters:
fraction
- between 0.0 and 1.0rng
- an IRNG that will be used to get a random starting point in the Sobol sequence this uses internallylimit
- how many Coord values this should return, at most; typically this will return less- Returns:
- a Coord array that may not have the full fraction used; you have been advised
-
mixedRandomSeparated
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with a fixed seed, but is very good at avoiding overlap (just as good asseparatedRegionZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Does not restrict the size of the returned array other than only using up tofraction * size()
cells.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
mixedRandomSeparated
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with a fixed seed, but is very good at avoiding overlap (just as good asseparatedRegionZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return- Returns:
- a freshly-allocated Coord array containing the pseudo-random cells
-
mixedRandomSeparated
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with the given seed (which will be made into an odd number if it is not one already), and is very good at avoiding overlap (just as good asseparatedZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to returnseed
- a long seed to change the points; the most significant 21 bits (except the sign bit) and least significant bit are ignored- Returns:
- a freshly-allocated Coord array containing the pseudo-random cells
-
mixedRandomRegion
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with a fixed seed, and is very good at avoiding overlap (just as good asseparatedRegionZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Does not restrict the count of "on" cells after this returns other than by only using up tofraction * size()
cells.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- this for chaining
-
mixedRandomRegion
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with a fixed seed, and is very good at avoiding overlap (just as good asseparatedRegionZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Restricts the total count of "on" cells after this returns to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the count.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum count of "on" cells to keep- Returns:
- this for chaining
-
mixedRandomRegion
Modifies this GreasedRegion so it contains a deterministic but random-seeming subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with the given seed (which will be made into an odd number if it is not one already), and is very good at avoiding overlap (just as good asseparatedZCurve(double, int)
, and probably faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Restricts the total count of "on" cells after this returns to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the count.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum count of "on" cells to keep- Returns:
- this for chaining
-
quasiRandomSeparated
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Does not restrict the size of the returned array other than only using up tofraction * size()
cells.
You can choose betweenmixedRandomSeparated(double)
,separatedZCurve(double)
,separatedBlue(double)
, and this method, where all are quasi-random, mixedRandom and separatedBlue are probably fastest, ZCurve and separatedBlue may have better 2-dimensional gaps between cells, and this method is somewhere in the middle.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
quasiRandomSeparated
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.
You can choose betweenmixedRandomSeparated(double)
,separatedZCurve(double)
,separatedBlue(double)
, and this method, where all are quasi-random, mixedRandom and separatedBlue are probably fastest, ZCurve and separatedBlue may have better 2-dimensional gaps between cells, and this method is somewhere in the middle.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
quasiRandomRegion
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Does not restrict the count of "on" cells after this returns other than by only using up tofraction * size()
cells.
You can choose betweenmixedRandomRegion(double)
,separatedRegionZCurve(double)
,separatedRegionBlue(double)
, and this method, where all are quasi-random, mixedRandom and separatedRegionBlue are probably fastest, ZCurve and separatedRegionBlue may have better 2-dimensional gaps between cells, and this method is somewhere in the middle.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- this for chaining
-
quasiRandomRegion
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Restricts the total count of "on" cells after this returns to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the count.
You can choose betweenmixedRandomRegion(double)
,separatedRegionZCurve(double)
,separatedRegionBlue(double)
, and this method, where all are quasi-random, mixedRandom and separatedRegionBlue are probably fastest, ZCurve and separatedRegionBlue may have better 2-dimensional gaps between cells, and this method is somewhere in the middle.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum count of "on" cells to keep- Returns:
- this for chaining
-
fray
Likeretract()
, this removes the "on" cells that are 4-way-adjacent to any "off" cell, but unlike that method it keeps a fraction of those surface cells, quasi-randomly selecting them. This can be thought of as runningsurface()
on a copy of this GreasedRegion, runningquasiRandomRegion(double)
on that surface with the given fractionKept, taking the original GreasedRegion and removing its whole surface withretract()
, then inserting the quasi-randomly-removed surface into this GreasedRegion to replace its surface with a randomly "damaged" one.- Parameters:
fractionKept
- the fraction between 0.0 and 1.0 of how many cells on the outer surface of this to keep "on"- Returns:
- this for chaining
-
randomScatter
Modifies this GreasedRegion so it contains a random subset of its previous contents, choosing cells so that the distance between any two "on" cells is at leastminimumDistance
, with at least one cell as "on" if any were "on" in this originally. Does not limit the count of "on" cells in the result.- Parameters:
rng
- used to generate random positionsminimumDistance
- the minimum distance between "on" cells in the result- Returns:
- this for chaining
-
randomScatter
Modifies this GreasedRegion so it contains a random subset of its previous contents, choosing cells so that the distance between any two "on" cells is at leastminimumDistance
, with at least one cell as "on" if any were "on" in this originally. Restricts the total count of "on" cells after this returns to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the count.- Parameters:
rng
- used to generate random positionsminimumDistance
- the minimum distance between "on" cells in the resultlimit
- the maximum count of "on" cells to keep- Returns:
- this for chaining
-
rateDensity
-
rateRegularity
-
perceptualHashQuick
Calculates a perceptual hash for this GreasedRegion using a method that is only precise for some sizes of GreasedRegion; it writes a result to into, and uses working as a temporary buffer. The lengths of into and working should be related; if into is length 1, then working should be length 64, and though the hash won't be very detailed, it will work well for images with width and height that are multiples of 8; if into is length 4, then working should be length 256, and this will work with more detail on images that have width and height that are multiples of 16. If working is null or is too small, then this won't reuse it and will allocate an appropriately-sized array for internal use.
Ported from https://github.com/commonsmachinery/blockhash/blob/master/blockhash.c , which is MIT-licensed.- Parameters:
into
- should be a long array of length 1 or 4; the contents don't matter and this will be where output is written toworking
- should be an int array of length 64 (if into has length 1) or 256 (if into has length 4); may be null if you like garbage collection
-
asCoords
-
asCoords
-
asEncoded
-
asTightEncoded
-
getAll
-
first
Gets the first Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty.- Returns:
- the first Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty
-
firstTight
-
last
Gets the last Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty.- Returns:
- the last Coord in the iteration order, or (-1,-1) if this GreasedRegion is empty
-
lastTight
-
nth
-
atFraction
-
atFractionTight
-
singleRandom
Gets a single random Coord from the "on" positions in this GreasedRegion, or the Coord (-1,-1) if this is empty. Uses the given IRNG to generate one random int, which is used as an index. The technique this uses to iterate over bits can be credited to Erling Ellingsen and Daniel Lemire, found here, and seems to be a little faster than the previous method. The fastest way to get a random Coord from a GreasedRegion is to avoid iterating over the bits at all, so if your region data doesn't change you should get it as a Coord array withasCoords()
and callIRNG.getRandomElement(Object[])
with that array as the parameter. If you take the asCoords() call out of consideration, getting random elements out of an array (especially a large one) can be hundreds of times faster. -
singleRandomTight
-
interleaveBits
Narrow-purpose; takes an x and a y value, each between 0 and 65535 inclusive, and interleaves their bits so the least significant bit and every other bit after it are filled with the bits of x, while the second-least-significant bit and every other bit after that are filled with the bits of y. Essentially, this takes two numbers with bits labeled likea b c
for x andR S T
for y and makes a number with those bits arranged likeR a S b T c
.- Parameters:
x
- an int between 0 and 65535, inclusivey
- an int between 0 and 65535, inclusive- Returns:
- an int that interleaves x and y, with x in the least significant bit position
-
disperseBits
Narrow-purpose; takes an int that represents a distance down the Z-order curve and moves its bits around so that its x component is stored in the bottom 16 bits (use(n & 0xffff)
to obtain) and its y component is stored in the upper 16 bits (use(n >>> 16)
to obtain). This may be useful for ordering traversals of all points in a GreasedRegion less predictably.- Parameters:
n
- an int that has already been interleaved, though this can really be any int- Returns:
- an int with x in its lower bits (
x = n & 0xffff;
) and y in its upper bits (y = n >>> 16;
)
-
nthZCurve
Likenth(int)
, this gets the Coord at a given index along a path through the GreasedRegion, but unlike nth(), this traverses the path in a zig-zag pattern called the Z-Order Curve. This method is often not very fast compared to nth(), but this different path can help if iteration needs to seem less regular while still covering all "on" cells in the GresedRegion eventually.- Parameters:
index
- the distance along the Z-order curve to travel, only counting "on" cells in this GreasedRegion.- Returns:
- the Coord at the given distance, or the Coord with x and y both -1 if index is too high or low
-
nthZCurveTight
Likenth(int)
, this finds a given index along a path through the GreasedRegion, but unlike nth(), this traverses the path in a zig-zag pattern called the Z-Order Curve, and unlikenthZCurve(int)
, this does not return a Coord and instead produces a "tight"-encoded int. This method is often not very fast compared to nth(), but this different path can help if iteration needs to seem less regular while still covering all "on" cells in the GreasedRegion eventually, and the tight encoding may be handy if you need to use ints.- Parameters:
index
- the distance along the Z-order curve to travel, only counting "on" cells in this GreasedRegion.- Returns:
- the "tight" encoded point at the given distance, or -1 if index is too high or low
-
separatedZCurve
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Contrast withmixedRandomSeparated(double, int)
, which tends to overlap more frequently. This method seems to work well because it chooses quasi-random points by their index in the Z-Order Curve as opposed to the simpler approach mixedRandomSeparated uses to traverse points (which just runs through the "on" cells a column at a time, not caring if two points are in adjacent cells as long as they are in different columns). Testing with a dungeon layout of mostly-on cells, this method has no overlap with a fraction of 0.4, while mixedRandomSeparated has overlap as early as 0.15 for fraction, and it only gets worse at higher values. A change to the algorithm used byquasiRandomSeparated(double)
has it overlapping at the same rate as this method, though it should be much faster. This method can be especially slow, since each Z-Order traversal may need to try many cells that are outside the GreasedRegion but are on the Z-Order Curve. Does not restrict the size of the returned array other than only using up tofraction * size()
cells.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
separatedZCurve
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Contrast withmixedRandomSeparated(double, int)
, which tends to overlap more frequently. This method seems to work well because it chooses quasi-random points by their index in the Z-Order Curve as opposed to the simpler approach mixedRandomSeparated uses to traverse points (which just runs through the "on" cells a column at a time, not caring if two points are in adjacent cells as long as they are in different columns). Testing with a dungeon layout of mostly-on cells, this method has no overlap with a fraction of 0.4, while mixedRandomSeparated has overlap as early as 0.15 for fraction, and it only gets worse at higher values. A change to the algorithm used byquasiRandomSeparated(double, int)
has it overlapping at the same rate as this method, though it should be much faster. This method can be especially slow, since each Z-Order traversal may need to try many cells that are outside the GreasedRegion but are on the Z-Order Curve. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
separatedRegionZCurve
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Contrast withmixedRandomRegion(double)
, which tends to overlap more frequently. This method seems to work well because it chooses quasi-random points by their index in the Z-Order Curve as opposed to the simpler approach mixedRandomRegion uses to traverse points (which just runs through the "on" cells a column at a time, not caring if two points are in adjacent cells as long as they are in different columns). Testing with a dungeon layout of mostly-on cells, this method has no overlap with a fraction of 0.4, while mixedRandomRegion has overlap as early as 0.15 for fraction, and it only gets worse at higher values. A change to the algorithm used byquasiRandomRegion(double)
has it overlapping at the same rate as this method, though it should be much faster. This method can be especially slow, since each Z-Order traversal may need to try many cells that are outside the GreasedRegion but are on the Z-Order Curve. Does not restrict the size of the returned array other than only using up tofraction * size()
cells.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- this, after modifications, for chaining
-
separatedRegionZCurve
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it is somewhat less likely to produce nearby cells in the result. If you request too many cells (too high of a value for fraction), it will start to overlap, however. Contrast withmixedRandomRegion(double, int)
, which tends to overlap more frequently. This method seems to work well because it chooses quasi-random points by their index in the Z-Order Curve as opposed to the simpler approach mixedRandomRegion uses to traverse points (which just runs through the "on" cells a column at a time, not caring if two points are in adjacent cells as long as they are in different columns). Testing with a dungeon layout of mostly-on cells, this method has no overlap with a fraction of 0.4, while mixedRandomRegion has overlap as early as 0.15 for fraction, and it only gets worse at higher values. A change to the algorithm used byquasiRandomRegion(double, int)
has it overlapping at the same rate as this method, though it should be much faster. This method can be especially slow, since each Z-Order traversal may need to try many cells that are outside the GreasedRegion but are on the Z-Order Curve. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return- Returns:
- this, after modifications, for chaining
-
separatedBlue
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it uses blue noise to sharply limit the likelihood of nearby points being chosen when fraction is small. If you request too many cells (too high of a value for fraction), it will start to have nearby cells, however. Does not restrict the size of the returned array other than only using up tofraction * size()
cells.
Also take a look atseparatedZCurve(double, int)
,quasiRandomSeparated(double, int)
,mixedRandomSeparated(double, int, long)
, andseparatedRegionBlue(double, int)
. Internally, this is a thin wrapper aroundseparatedRegionBlue(double, int)
, and won't be more efficient than that method.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
separatedBlue
Gets a Coord array from the "on" contents of this GreasedRegion, using a quasi-random scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it uses blue noise to sharply limit the likelihood of nearby points being chosen when fraction is small. If you request too many cells (too high of a value for fraction), it will start to have nearby cells, however. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.
Also take a look atseparatedZCurve(double, int)
,quasiRandomSeparated(double, int)
,mixedRandomSeparated(double, int, long)
, andseparatedRegionBlue(double, int)
. Internally, this is a thin wrapper aroundseparatedRegionBlue(double, int)
, and won't be more efficient than that method.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return; may return less- Returns:
- a freshly-allocated Coord array containing the quasi-random cells
-
separatedRegionBlue
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it uses blue noise to sharply limit the likelihood of nearby points being chosen when fraction is small. If you request too many cells (too high of a value for fraction), it will start to have nearby cells, however. Does not restrict the size of the returned GreasedRegion other than only using up tofraction * size()
cells.
Also take a look atseparatedRegionZCurve(double, int)
,quasiRandomRegion(double, int)
,mixedRandomRegion(double, int, long)
, andseparatedBlue(double, int)
.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0- Returns:
- this, after modifications, for chaining
-
separatedRegionBlue
Modifies this GreasedRegion so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()
matches the givenfraction
of the total amount of "on" cells in this. This is quasi- random instead of pseudo-random because it uses blue noise to sharply limit the likelihood of nearby points being chosen when fraction is small. If you request too many cells (too high of a value for fraction), it will start to have nearby cells, however. Restricts the total size of the returned GreasedRegion to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.
Also take a look atseparatedRegionZCurve(double, int)
,quasiRandomRegion(double, int)
,mixedRandomRegion(double, int, long)
, andseparatedBlue(double, int)
.- Parameters:
fraction
- the fraction of "on" cells to quasi-randomly select, between 0.0 and 1.0limit
- the maximum size of the array to return; may return less- Returns:
- this, after modifications, for chaining
-
randomPortion
-
randomRegion
-
contains
- Specified by:
contains
in interfaceZone
- Overrides:
contains
in classZone.Skeleton
- Returns:
- Whether this zone contains the coordinate (x,y).
-
isEmpty
- Specified by:
isEmpty
in interfaceCollection<Coord>
- Specified by:
isEmpty
in interfaceZone
- Returns:
- Whether this zone is empty.
-
sum
Generates a 2D int array from an array or vararg of GreasedRegions, starting at all 0 and adding 1 to the int at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions
- an array or vararg of GreasedRegions; must all have the same width and height- Returns:
- a 2D int array with the same width and height as the regions, where an int cell equals the number of given GreasedRegions that had an "on" cell at that position
-
sum
Generates a 2D int array from a List of GreasedRegions, starting at all 0 and adding 1 to the int at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions
- a List of GreasedRegions; must all have the same width and height- Returns:
- a 2D int array with the same width and height as the regions, where an int cell equals the number of given GreasedRegions that had an "on" cell at that position
-
sumDouble
Generates a 2D double array from an array or vararg of GreasedRegions, starting at all 0 and adding 1 to the double at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions
- an array or vararg of GreasedRegions; must all have the same width and height- Returns:
- a 2D double array with the same width and height as the regions, where an double cell equals the number of given GreasedRegions that had an "on" cell at that position
-
sumDouble
Generates a 2D double array from a List of GreasedRegions, starting at all 0 and adding 1 to the double at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions
- a List of GreasedRegions; must all have the same width and height- Returns:
- a 2D double array with the same width and height as the regions, where an double cell equals the number of given GreasedRegions that had an "on" cell at that position
-
sumWeighted
Generates a 2D int array from an array of GreasedRegions and an array of weights, starting the 2D result at all 0 and, for every GreasedRegion that has that cell as "on," adding the int in the corresponding weights array at the position of that cell. This means if you give an array of 4 GreasedRegions to this method along with the weights1, 2, 3, 4
, it can produce a number between 0 and 10 in a cell (where 10 is used when all 4 GreasedRegions have a cell "on," since1 + 2 + 3 + 4 == 10
); if the weights are instead1, 10, 100, 1000
, then the results can vary between 0 and 1111, where 1111 is only if all GreasedRegions have a cell as "on." The weights array must have a length at least equal to the length of the regions array.- Parameters:
regions
- an array of GreasedRegions; must all have the same width and heightweights
- an array of ints; must have length at least equal to regions' length- Returns:
- a 2D int array with the same width and height as the regions, where an int cell equals the sum of the weights corresponding to GreasedRegions that had an "on" cell at that position
-
sumWeightedDouble
Generates a 2D double array from an array of GreasedRegions and an array of weights, starting the 2D result at all 0 and, for every GreasedRegion that has that cell as "on," adding the double in the corresponding weights array at the position of that cell. This means if you give an array of 4 GreasedRegions to this method along with the weights1, 2, 3, 4
, it can produce a number between 0 and 10 in a cell (where 10 is used when all 4 GreasedRegions have a cell "on," since1 + 2 + 3 + 4 == 10
); if the weights are instead1, 10, 100, 1000
, then the results can vary between 0 and 1111, where 1111 is only if all GreasedRegions have a cell as "on." The weights array must have a length at least equal to the length of the regions array.- Parameters:
regions
- an array of GreasedRegions; must all have the same width and heightweights
- an array of doubles; must have length at least equal to regions' length- Returns:
- a 2D double array with the same width and height as the regions, where an double cell equals the sum of the weights corresponding to GreasedRegions that had an "on" cell at that position
-
sumInto
Adds to an existing 2D int array with an array or vararg of GreasedRegions, adding 1 to the int in existing at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can increase the value in existing by any number between 0 and 16 in a cell.- Parameters:
existing
- a non-null 2D int array that will have each cell incremented by the sum of the GreasedRegionsregions
- an array or vararg of GreasedRegions; must all have the same width and height- Returns:
- existing, after modification, where an int cell will be changed by the number of given GreasedRegions that had an "on" cell at that position
-
sumIntoDouble
Adds to an existing 2D double array with an array or vararg of GreasedRegions, adding 1 to the double in existing at a position once for every GreasedRegion that has that cell as "on." This means if you give 8 GreasedRegions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 GreasedRegions, then it can increase the value in existing by any number between 0 and 16 in a cell.- Parameters:
existing
- a non-null 2D double array that will have each cell incremented by the sum of the GreasedRegionsregions
- an array or vararg of GreasedRegions; must all have the same width and height- Returns:
- existing, after modification, where a double cell will be changed by the number of given GreasedRegions that had an "on" cell at that position
-
dijkstraScan
Discouraged from active use; slower thanDijkstraMap
and has less features.- Parameters:
map
- a 2D char array where '#' is a wallgoals
- an array or vararg of Coord to get the distances toward- Returns:
- a 2D double array of distances from a cell to the nearest goal
-
dijkstraScan8way
Discouraged from active use; slower thanDijkstraMap
and has less features.- Parameters:
map
- a 2D char array where '#' is a wallgoals
- an array or vararg of Coord to get the distances toward- Returns:
- a 2D double array of distances from a cell to the nearest goal
-
bitSum
Generates a 2D int array from an array or vararg of GreasedRegions, treating each cell in the nth region as the nth bit of the int at the corresponding x,y cell in the int array. This means if you give 8 GreasedRegions to this method, it can produce any 8-bit number in a cell (0-255); if you give 16 GreasedRegions, then it can produce any 16-bit number (0-65535).- Parameters:
regions
- an array or vararg of GreasedRegions; must all have the same width and height- Returns:
- a 2D int array with the same width and height as the regions, with bits per int taken from the regions
-
equals
- Specified by:
equals
in interfaceCollection<Coord>
- Overrides:
equals
in classObject
-
hashCode
- Specified by:
hashCode
in interfaceCollection<Coord>
- Overrides:
hashCode
in classObject
-
hash64
-
hash64
Computes a 64-bit hash code of this GreasedRegion given a 64-bit seed; even if given two very similar seeds, this should produce very different hash codes for the same GreasedRegion.
Meant for potential use in Bloom filters. UsesCrossHash.Yolk
's algorithm(s).- Parameters:
seed
- a seed that will determine how the hashing algorithm works; all 64 bits are used.- Returns:
- a 64-bit hash code for this GreasedRegion
-
serializeToString
-
deserializeFromString
-
of
Constructs a GreasedRegion using a vararg for data. Primarily meant for generated code, sinceserializeToString()
produces a String that happens to be a valid parameter list for this method.- Parameters:
width
- width of the GreasedRegion to produceheight
- height of the GreasedRegion to producedata
- array or vararg of long containing the exact data, probably from an existing GreasedRegion- Returns:
- a new GreasedRegion with the given width, height, and data
-
toCompressedString
Compresses this GreasedRegion into a UTF-16 String and returns the String without modifying this GreasedRegion. UsesCoordPacker
's algorithm and data to compress this GreasedRegion in 256x128 blocks, storing the CoordPacker-like data as chars with values from 256 to 33023 (a concept also used inLZSEncoding
), and using ASCII semicolons to separate them or store other info (just width and height, which are given first as 16 hex digits). This finishes by running the result throughLZSEncoding
, a combination which typically gets very good compression.- Returns:
- a String that could be used to reconstruct this GreasedRegion using
decompress(String)
-
decompress
Decompresses a String returned bytoCompressedString()
, returning a new GreasedRegion with identical width, height, and contents to the GreasedRegion before compression. This decompresses theLZSEncoding
applied to the data, then decompresses theCoordPacker
-type Hilbert Curve RLE data to get the original GreasedRegion back.- Parameters:
compressed
- a String that was compressed bytoCompressedString()
, without changes- Returns:
- a new copy of the GreasedRegion that was previously compressed
-
contains
- Specified by:
contains
in interfaceCollection<Coord>
-
iterator
- Specified by:
iterator
in interfaceCollection<Coord>
- Specified by:
iterator
in interfaceIterable<Coord>
- Overrides:
iterator
in classZone.Skeleton
-
toArray
- Specified by:
toArray
in interfaceCollection<Coord>
-
toArray
- Specified by:
toArray
in interfaceCollection<Coord>
-
add
- Specified by:
add
in interfaceCollection<Coord>
-
clear
- Specified by:
clear
in interfaceCollection<Coord>
-
remove
- Specified by:
remove
in interfaceCollection<Coord>
-
containsAll
- Specified by:
containsAll
in interfaceCollection<Coord>
-
addAll
- Specified by:
addAll
in interfaceCollection<Coord>
-
removeAll
- Specified by:
removeAll
in interfaceCollection<Coord>
-
retainAll
- Specified by:
retainAll
in interfaceCollection<Coord>
-
deteriorate
Randomly removes points from a GreasedRegion, with larger values for preservation keeping more of the existing shape intact. If preservation is 1, roughly 1/2 of all points will be removed; if 2, roughly 1/4, if 3, roughly 1/8, and so on, so that preservation can be thought of as a negative exponent of 2.- Parameters:
rng
- used to determine random factorspreservation
- roughly what degree of points to remove (higher keeps more); removes about1/(2^preservation)
points- Returns:
- a randomly modified change to this GreasedRegion
-
deteriorate
Randomly removes points from a GreasedRegion, with preservation as a fraction between 1.0 (keep all) and 0.0 (remove all). If preservation is 0.5, roughly 1/2 of all points will be removed; if 0.25, roughly 3/4 will be removed (roughly 0.25 will be _kept_), if 0.8, roughly 1/5 will be removed (and about 0.8 will be kept), and so on. Preservation must be between 0.0 and 1.0 for this to have the intended behavior; 1.0 or higher will keep all points without change (returning this GreasedRegion), while anything less than 0.015625 (1.0/64) will empty this GreasedRegion (usingempty()
) and then return it. The parameterrandom
can be an object like aDiverRNG
, anRNG
backed by a well-distributed RandomnessSource like its default, DiverRNG, aGWTRNG
(especially if you target GWT, where it will perform much better than most alternatives), or any of various other RandomnessSource implementations that distribute bits well forRandomnessSource.nextLong()
, but should not be intentionally-biased RNGs likeDharmaRNG
orEditRNG
, nor double-based QRNGs likeVanDerCorputQRNG
orSobolQRNG
. -
toggle
Changes the on/off state of the cell with the given x and y, making an on cell into an off cell, or an off cell into an on cell.
This was called flip(), but that name would be confusing since flipping a rectangular area usually means reversing an axis.- Parameters:
x
- the x position of the cell to flipy
- the y position of the cell to flip- Returns:
- this for chaining, modified
-
mirrorY
Returns a new GreasedRegion that has been mirrored along the rightmost edge, parallel to the y-axis. The new GreasedRegion will have exactly twice the width, the additional width will have the contents of the original GreasesRegion in reversed order. The positions shared by both GreasedRegions will be the same, that is, any area not added to the original will be equal to the original.- Returns:
- a new GreasedRegion with twice the width of
this
, that is mirrored along the rightmost edge
-
intersectsWith
- Specified by:
intersectsWith
in interfaceZone
- Overrides:
intersectsWith
in classZone.Skeleton
- Returns:
- true if
this
andother
have a common cell.
-
translate
Translates a copy ofthis
by the x,y values inc
. Implemented withreturn copy().translate(c.x, c.y);
- Specified by:
translate
in interfaceZone
- Overrides:
translate
in classZone.Skeleton
- Returns:
this
copied and shifted by(c.x,c.y)
-
getExternalBorder
Gets a Collection of Coord values that are not in this GreasedRegion, but are adjacent to it, either orthogonally or diagonally. Related to the fringe() methods in CoordPacker and GreasedRegion, but guaranteed to use 8-way adjacency and to return a new Collection of Coord. This implementation returns a GreasedRegion produced simply byreturn copy().fringe8way();
.- Specified by:
getExternalBorder
in interfaceZone
- Overrides:
getExternalBorder
in classZone.Skeleton
- Returns:
- Cells adjacent to
this
(orthogonally or diagonally) that aren't inthis
-
extend
Gets a new Zone that contains all the Coords inthis
plus all neighboring Coords, which can be orthogonally or diagonally adjacent to any Coord this has in it. Related to the expand() methods in CoordPacker and GreasedRegion, but guaranteed to use 8-way adjacency and to return a new Zone. This implementation returns a GreasedRegion produced simply byreturn copy().expand8way();
.- Specified by:
extend
in interfaceZone
- Overrides:
extend
in classZone.Skeleton
- Returns:
- A new GreasedRegion where "off" cells adjacent to
this
(orthogonally or diagonally) have been added to the "on" cells inthis
-
contains
Checks ifc
is present in this GreasedRegion. Returns true if and only if c is present in this GreasedRegion as an "on" cell. This will never be true if c is null, has negative x or y, has a value for x that is equal to or greater thanwidth
, or has a value for y that is equal to or greater thanheight
, but none of those conditions will cause Exceptions to be thrown.- Specified by:
contains
in interfaceZone
- Overrides:
contains
in classZone.Skeleton
- Parameters:
c
- a Coord to try to find in this GreasedRegion; if null this will always return false- Returns:
- true if
c
is an "on" cell in this GreasedRegion, or false otherwise, including if c is null
-
contains
Checks whether all Coords inother
are also present inthis
. Requires thatother
won't give a null Coord while this method iterates over it.- Specified by:
contains
in interfaceZone
- Overrides:
contains
in classZone.Skeleton
- Parameters:
other
- another Zone, such as a GreasedRegion or aCoordPackerZone
- Returns:
- true if all Coords in other are "on" in this GreasedRegion, or false otherwise
-
xBound
- Specified by:
xBound
in interfaceZone
- Overrides:
xBound
in classZone.Skeleton
- Parameters:
findSmallest
- if true, finds the smallest x-coordinate value; if false, finds the biggest.- Returns:
- The x-coordinate of the Coord within
this
that has the smallest (or biggest) x-coordinate. Or -1 if the zone is empty.
-
yBound
- Specified by:
yBound
in interfaceZone
- Overrides:
yBound
in classZone.Skeleton
- Parameters:
findSmallest
- if true, finds the smallest y-coordinate value; if false, finds the biggest.- Returns:
- The y-coordinate of the Coord within
this
that has the smallest (or biggest) y-coordinate. Or -1 if the zone is empty.
-
getWidth
Gets the distance between the minimum x-value contained in this GreasedRegion and the maximum x-value in it. Not the same as accessing the fieldwidth
on a GreasedRegion! The field will get the span of the space that the GreasedRegion can use, including "on" and "off" cells. This method will only get the distance between the furthest-separated "on" cells on the x-axis, and won't consider "off" cells. This method can return -1 if the GreasedRegion is empty, 0 if the "on" cells are all in a vertical line (that is, when the minimum x is equal to the maximum x), or a positive int in other cases with multiple x-values.- Specified by:
getWidth
in interfaceZone
- Overrides:
getWidth
in classZone.Skeleton
- Returns:
- the distance on the x-axis between the "on" cell with the lowest x-value and the one with the highest
-
getHeight
Gets the distance between the minimum y-value contained in this GreasedRegion and the maximum y-value in it. Not the same as accessing the fieldheight
on a GreasedRegion! The field will get the span of the space that the GreasedRegion can use, including "on" and "off" cells. This method will only get the distance between the furthest-separated "on" cells on the y-axis, and won't consider "off" cells. This method can return -1 if the GreasedRegion is empty, 0 if the "on" cells are all in a horizontal line (that is, when the minimum y is equal to the maximum y), or a positive int in other cases with multiple y-values.- Specified by:
getHeight
in interfaceZone
- Overrides:
getHeight
in classZone.Skeleton
- Returns:
- the distance on the y-axis between the "on" cell with the lowest y-value and the one with the highest
-
getDiagonal
Gets the diagonal distance from the point combining the lowest x-value present in this GreasedRegion with the lowest y-value in this, to the point combining the highest x-value and the highest y-value. These minimum and maximum values don't necessarily match a single "on" cell for each min and max corner, and can take their x and y values from two different points. The diagonal distance uses Euclidean measurement (basic Pythagorean Theorem math here), and will be a double.- Specified by:
getDiagonal
in interfaceZone
- Overrides:
getDiagonal
in classZone.Skeleton
- Returns:
- the diagonal distance from (min x, min y) to (max x, max y), as a double
-
getInternalBorder
- Specified by:
getInternalBorder
in interfaceZone
- Overrides:
getInternalBorder
in classZone.Skeleton
- Returns:
- Cells in
this
that are adjacent to a cell not inthis
-
mixedRandomSeparatedAlt
Gets a Coord array from the "on" contents of this GreasedRegion, using a deterministic but random-seeming scattering of chosen cells with a count that matches the givenfraction
of the total amount of "on" cells in this. This is pseudo-random with the given seed (which will be made into an odd number if it is not one already), and is very good at avoiding overlap (just as good asseparatedZCurve(double, int)
, and much faster). If you request too many cells (too high of a value for fraction), it will start to overlap, but a fraction value of 0.4 reliably has had no overlap in testing. Restricts the total size of the returned array to a maximum oflimit
(minimum is 0 if no cells are "on"). If limit is negative, this will not restrict the size.- Parameters:
fraction
- the fraction of "on" cells to randomly select, between 0.0 and 1.0limit
- the maximum size of the array to returnseed
- a long seed to change the points; the most significant 21 bits (except the sign bit) and least significant bit are ignored- Returns:
- a freshly-allocated Coord array containing the pseudo-random cells
-