Class Region
java.lang.Object
com.github.yellowstonegames.grid.Region
- All Implemented Interfaces:
Iterable<Coord>, Collection<Coord>
Region encoding of on/off information about areas using bitsets; uncompressed but fast at bulk operations.
This can handle any size of 2D data, but it's almost always best for the Coord pool to be at least as large
as the max dimensions of a Region (use
Each Region is mutable, and instance methods typically modify that instance and return it for chaining. There are exceptions, usually where multiple Region values are returned and the instance is not modified.
Typical usage involves constructing a Region from some input data, like a char[][] for a map or a float[][] from DijkstraMap, and modifying it spatially with expand(), retract(), flood(), etc. It's common to mix in data from other Regions with and() (which gets the intersection of two Regions 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 Regions), 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. There's really quite a lot of methods here that modify a Region, so here's a partial list:
Once you have a Region, you may want to:
You may also want to produce some 2D data from one or more Regions, as with
For efficiency, you can place one Region into another (typically a temporary value that is no longer needed and can be recycled) using
Coord.expandPoolTo(int, int) to ensure this). 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 very
fast at certain bulk operations (anything that expands or retracts an area, including expand(),
retract(), fringe(), surface(), and flood(Region), and maintains the high speed
at "bitwise-like" operations that bitsets typically have (for example, on and(Region), or(Region),
and xor(Region)).
Each Region is mutable, and instance methods typically modify that instance and return it for chaining. There are exceptions, usually where multiple Region values are returned and the instance is not modified.
Typical usage involves constructing a Region from some input data, like a char[][] for a map or a float[][] from DijkstraMap, and modifying it spatially with expand(), retract(), flood(), etc. It's common to mix in data from other Regions with and() (which gets the intersection of two Regions 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 Regions), 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. There's really quite a lot of methods here that modify a Region, so here's a partial list:
expand()changes any cells next to a currently "on" cell to also be "on." It's 4-way, and has an 8-way variantexpand8way(). There's an overload that expands several times as if by a loop,expand(int), which also has an 8-way variant. You can useexpandSeries(int)to get multiple Regions produced as intermediate values of a series of expansions; this also has an 8-way variant.expandSeriesToLimit()returns an ObjectList of as many Regions as it takes to expand until no more cells can change.retract()is just likeexpand(), but changes any "on" cells that are next to an "off" cell to also be "off." It can be thought of as expanding the "off" cells, with the subtle difference that the edges are also considered "off" here. All of the above variants ofexpand()listed above have equivalents forretract(), likeretractSeriesToLimit().fringe()is likeexpand(), but doesn't keep the old contents of the Region, only the cells that are added. This has some differences in howfringe(int)works (it returns a multiple-cell-thick fringe section, still not containing any of the original), and howfringeSeries(int)works (it returns many single-cell-thick fringe sections). There's afringeSeriesToLimit(), too.surface()is something like removing the result ofretract()from this Region; it gets only those "on" cells that are next to an "off" cell. Like withfringe(), the variants are a little different;surface(int)gets a multiple-cell deep surface, andsurfaceSeries(int)gets a series of single-cell deep rings from further and further inside the original Region. Yes, there's also asurfaceSeriesToLimit().flood(Region)is useful; it acts likeexpand(), but won't change any cells unless they are "on" in itsboundsargument, another Region. There's alsoflood(Region, int), which may be most useful with a very largeamountparameter to fill up the bounds completely with whatever the original Region could reach.flood8way(Region),floodSeries(Region, int), andfloodSeriesToLimit(Region)are all here, too.spill(Region, int, EnhancedRandom)is like callingflood(Region)many times, but only expanding one cell on the edge each time, randomly choosing it. As long asvolumeis not enough to fully fill the reachable part ofbounds, the filled area will be random but always connected.- Various random modifications:
randomRegion(EnhancedRandom, int)simply chooses "on" points from this Region until it reachessize,deteriorate(EnhancedRandom, float)randomly removes points but stops when the fraction of cells remaining is equal topreservation,fray(float)acts likedeteriorate(EnhancedRandom, float)but only affects the surface (whatsurface()would return), anddisperseRandom(EnhancedRandom)randomly removes one of each pair of "on" cells. - Various quasi-random modifications: Mostly you should use
separatedRegionBlue(float)if you want to get an approximate fraction of well-separated "on" cells from a Region.fray(float)also has a quasi-random version that doesn't use a RandomnessSource.
Once you have a Region, you may want to:
- get a single random point from it (use
singleRandom(EnhancedRandom)), - get several random points from it with random sampling (use
randomPortion(EnhancedRandom, int)), - mutate the current Region to keep random points from it with random sampling (use
randomRegion(EnhancedRandom, int)), - get random points that are likely to be separated (use
randomScatter(EnhancedRandom, int)on a copy, orseparatedBlue(float)if you don't want a random aspect), - do what any of the above "separated" methods can do, but mutate the current Region (use
separatedRegionBlue(float)), - 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
writeCharsToOff(char[][], char),writeChars(char[][], char),writeFloats(float[][], float), orwriteIntsInto(int[][], int), along with variations on those.
You may also want to produce some 2D data from one or more Regions, as with
sum(Region...) or
toChars(). The most effective techniques regarding Region involve multiple methods, like getting a
few random points from an existing Region representing floor tiles in a dungeon with
randomRegion(EnhancedRandom, int), then finding a random expansion of those initial points with
spill(Region, int, EnhancedRandom), giving the original Region 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 Region into another (typically a temporary value that is no longer needed and can be recycled) using
remake(Region), or give the information that would normally be used to
construct a fresh Region 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.-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final Region[]A 256-element array ofRegions, each 64x64, where the first Region has an impossibly strict threshold on what points to include (it is empty), but the second has some points far apart, the third has more, and so on until the last element includes almost all points.long[]intint -
Constructor Summary
ConstructorsConstructorDescriptionRegion()Constructs an empty 4x64 Region.Region(boolean[][] bits) Constructs a Region 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."Region(boolean[] bits, int width, int height) Constructs a Region 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."Region(byte[][] map, int lower, int upper) Constructs this Region using a byte[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.Region(char[][] map, char yes) Constructs a Region 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."Region(char[][] map, char[] yes) Constructs a Region 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."Region(float[][] map, float upperBound) Constructs this Region using a float[][] (typically one generated by DijkstraMap) 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.Region(float[][] map, float lowerBound, float upperBound) Constructs this Region using a float[][] (typically one generated by DijkstraMap) that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else.Region(float[][] map, float lowerBound, float upperBound, int scale) Constructs this Region using a float[][] that only stores two relevant states: an "on" state for values between lowerBound (inclusive) and upperBound (exclusive), and an "off" state for anything else.Region(int[][] map, int yes) Constructs a Region 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."Region(int[][] map, int lower, int upper) Constructs this Region using an int[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.Region(int width, int height) Constructor for an empty Region of the given width and height.Constructor for a Region that can have several "on" cells specified, and has the given width and height.Constructor for a Region that can have several "on" cells specified, and has the given width and height.Region(long[] data2, int width, int height) Primarily for internal use, this constructor copies data2 exactly into the internal long array the new Region 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 Region are actually removed (this only matters if height is not a multiple of 64).Region(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 Region will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for the constructed Region.Region(short[][] map, int lower, int upper) Constructs this Region using a short[][], treating cells as on if they are greater than or equal to lower and less than upper, or off otherwise.Region(com.github.tommyettinger.function.IntIntPredicate decider, int width, int height) Constructs a Region with the given width and height by callingdecider's functional method on each x,y position for x from 0 (inclusive) to width (exclusive) and for y from 0 (inclusive) to height (exclusive).Region(com.github.tommyettinger.random.EnhancedRandom random, float fraction, int width, int height) Constructor for a random Region of the given width and height, trying to set the given fraction of cells to on.Region(com.github.tommyettinger.random.EnhancedRandom random, int width, int height) Constructor for a random Region of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off.Constructor for a Region that contains a single "on" cell, and has the given width and height.Constructs a Region with the given width and height by callingINoise.getNoise(float, float)position for x from 0 (inclusive) to width (exclusive) and for y from 0 (inclusive) to height (exclusive).Copy constructor that takes another Region and copies all of its data into this new one.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. -
Method Summary
Modifier and TypeMethodDescriptionbooleanbooleanaddAll(Collection<? extends Coord> c) allOn()Sets all cells in this to "on."alterBounds(int widthChange, int heightChange) Changes the width and/or height of this Region, enlarging or shrinking starting at the edges wherex == width - 1andy == height - 1.Intersection of two Regions, assigning the result into this Region.Difference of two Regions, assigning the result into this Region.andWrapping64(Region other) Intersection of two Regions, assigning the result into this Region, 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 Region.static Collection<Region> appendContaining(Collection<Region> into, int x, int y, Region... packed) Tries to look up the position x,y in each Region in packed; each Region that contains that x,y point is appended into the Collectioninto.static Collection<Region> appendContaining(Collection<Region> into, int x, int y, Collection<Region> packed) Tries to look up the position x,y in each Region in packed; each Region that contains that x,y point is appended into the Collectioninto.static longapproximateBits(com.github.tommyettinger.random.EnhancedRandom 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[]int[]int[]atFraction(float fraction) intatFractionTight(float fraction) static int[][]Generates a 2D int array from an array or vararg of Regions, treating each cell in the nth region as the nth bit of the int at the corresponding x,y cell in the int array.voidclear()connect()Takes the pairs of "on" cells in this Region that are separated by exactly one cell in an orthogonal line, and changes the gap cells to "on" as well.Takes the pairs of "on" cells in this Region that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.Takes the pairs of "on" cells in this Region that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.connectLines(Region buffer) Takes the pairs of "on" cells in this Region that are separated by exactly one cell in an orthogonal or diagonal line, and changes the gap cells to "on" as well.booleancontains(int x, int y) booleanChecks ifcis present in this Region.booleanbooleancontainsAll(Collection<?> c) copy()Simple method that returns a newly-allocated copy of this Region; modifications to one won't change the other, and this method returns the copy while leaving the original unchanged.copyRotated(int turns) Makes a copy of this Region that has been rotated 90 degreesturnstimes.boolean[][]decode()Returns this Region's data as a 2D boolean array, [width][height] in size, with on treated as true and off treated as false.static Regiondecompress(String compressed) Decompresses a String returned bytoCompressedString(), returning a new Region with identical width, height, and contents to the Region before compression.decompressInto(String compressed) Decompresses a String returned bytoCompressedString(), and assigns into this region the width, height, and contents of the data before compression.deteriorate(com.github.tommyettinger.random.EnhancedRandom random, float preservation) Randomly removes points from a Region, with preservation as a fraction between 1.0 (keep all) and 0.0 (remove all).deteriorate(com.github.tommyettinger.random.EnhancedRandom rng, int preservation) Randomly removes points from a Region, with larger values for preservation keeping more of the existing shape intact.int[][]dijkstraScan(int[][] into, Coord goal) A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available.int[][]dijkstraScan(int[][] into, Coord goal, int limit) A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available.int[][]dijkstraScan(int[][] into, Region goals) A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available.int[][]dijkstraScan(int[][] into, Region goals, int limit) A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available.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.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 intdisperseBits(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).disperseRandom(com.github.tommyettinger.random.EnhancedRandom 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).empty()Equivalent toclear(), setting all cells to "off," but also returns this for chaining.booleanexpand()Takes the "on" cells in this Region 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).expand(int amount) Takes the "on" cells in this Region and expands them byamountcells 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).Takes the "on" cells in this Region and expands them byamountcells 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).Takes the "on" cells in this Region 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).Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell take up a 3x3 square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).expand8way(int amount) Takes the "on" cells in this Region and expands them byamountcells in the 8 orthogonal and diagonal directions, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).expand8way(int amount, Region temp) Takes the "on" cells in this Region and expands them byamountcells in the 8 orthogonal and diagonal directions, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).expand8way(Region temp) Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell take up a 3x3 square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).Region[]expandSeries(int amount) Takes the "on" cells in this Region and producesamountRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous Region, 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).Region[]expandSeries8way(int amount) Takes the "on" cells in this Region and producesamountRegions, each one expanded by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).com.github.tommyettinger.ds.ObjectList<Region> Returns a new ObjectList of Region where each item is a progressively more and moreexpand()-ed copy of this Region, until ending where the entire Region is "on" cells.com.github.tommyettinger.ds.ObjectList<Region> Returns a new ObjectList of Region where each item is a progressively more and moreexpand8way()-ed copy of this Region, until just before the entire Region is "on" cells.fill(boolean contents) Sets all cells in this to "on" if contents is true, or "off" if contents is false.first()Gets the first Coord in the iteration order, or (-1,-1) if this Region is empty.intfit(float xFraction, float yFraction) int[][]fit(int[][] basis, int defaultValue) flip(boolean leftRight, boolean upDown) Likeexpand(), but limits expansion to the "on" cells ofbounds.Likeexpand(int), but limits expansion to the "on" cells ofbounds.Likeexpand(int), but limits expansion to the "on" cells ofbounds.Likeexpand(), but limits expansion to the "on" cells ofbounds.Likeexpand8way(), but limits expansion to the "on" cells ofbounds.Likeexpand8way(int), but limits expansion to the "on" cells ofbounds.Likeexpand8way(int), but limits expansion to the "on" cells ofbounds.Likeexpand8way(), but limits expansion to the "on" cells ofbounds.Region[]floodSeries(Region bounds, int amount) Repeatedly callsflood(Region)amounttimes and returns the intermediate steps in a Region array of sizeamount.Region[]floodSeries8way(Region bounds, int amount) Repeatedly callsflood8way(Region)amounttimes and returns the intermediate steps in a Region array of sizeamount.com.github.tommyettinger.ds.ObjectList<Region> floodSeriesToLimit(Region bounds) Repeatedly generates new Regions, each one cell expanded in 4 directions from the previous Region and staying inside the "on" cells ofbounds, until it can't expand any more.com.github.tommyettinger.ds.ObjectList<Region> floodSeriesToLimit8way(Region bounds) Repeatedly generates new Regions, each one cell expanded in 8 directions from the previous Region and staying inside the "on" cells ofbounds, until it can't expand anymore.fray(float 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.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.fray(com.github.tommyettinger.random.EnhancedRandom random, float 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, randomly selecting them.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, randomly selecting them.fringe()Takes the "on" cells in this Region and expands them by one cell in the 4 orthogonal directions, producing a diamond 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.fringe(int amount) Takes the "on" cells in this Region 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.Takes the "on" cells in this Region 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.Takes the "on" cells in this Region and expands them by one cell in the 4 orthogonal directions, producing a diamond 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.Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, producing a square shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (8-way) of an "on" cell.fringe8way(int amount) Takes the "on" cells in this Region and expands them by amount cells in the 8 orthogonal and diagonal directions (iteratively, producing a square shape), then removes the original area before expansion, producing only the cells that were "off" in this and within amount cells (8-way) of an "on" cell.fringe8way(int amount, Region temp, Region temp2) Takes the "on" cells in this Region and expands them by amount cells in the 8 orthogonal and diagonal directions (iteratively, producing a square shape), then removes the original area before expansion, producing only the cells that were "off" in this and withinamountcells (8-way) of an "on" cell.fringe8way(Region temp) Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, producing a square shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (8-way) of an "on" cell.Region[]fringeSeries(int amount) Takes the "on" cells in this Region and produces amount Regions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous Region, making each "on" cell take up a diamond-shaped area.Region[]fringeSeries8way(int amount) Takes the "on" cells in this Region and produces amount Regions, each one expanded by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region, making each "on" cell take up a square-shaped area.com.github.tommyettinger.ds.ObjectList<Region> Returns an ObjectList of progressively further-expanded copied fringes of this Region.com.github.tommyettinger.ds.ObjectList<Region> Returns an ObjectList of progressively further-expanded copied fringes of this Region.longhash64()longhash64(long seed) Computes a 64-bit hash code of this Region given a 64-bit seed; even if given two very similar seeds, this should produce very different hash codes for the same Region.inthashCode()insert(int tight) Sets the given cell, "tightly" encoded for a specific width/height as byasTightEncoded(), to "on".insert(int x, int y) Sets the cell at x,y to "on".Takes another Region, called other, with potentially different size and inserts its "on" cells into this Region at the given x,y offset, allowing negative x and/or y to put only part of other in this.Takes another Region, called other, with potentially different size and inserts its "on" cells into this Region at the given x,y offset, allowing negative x and/or y to put only part of other in this.Sets the cell at point to "on".insertCircle(Coord center, int radius) insertRectangle(int startX, int startY, int rectangleWidth, int rectangleHeight) insertSeveral(int[] points) insertSeveral(Coord... points) insertSeveral(Iterable<Coord> points) insertTranslation(int x, int y) Adds to this Region with a moved set of its own "on" cells, moved to the given x and y offset.insertTranslation(int x, int y, Region buffer) Adds to this Region with a moved set of its own "on" cells, moved to the given x and y offset.static intinterleaveBits(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.booleanintersects(Region other) Returns true if any cell is "on" in both this Region and in other; returns false otherwise.char[][]intoChars(char[][] chars, char on) Fills this Region's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteronand "off" cells left as-is.char[][]intoChars(char[][] chars, char on, char off) Fills this Region's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteronand "off" cells with the parameteroff.booleanisEmpty()iterator()Finds the largest contiguous area of "on" cells in this Region and returns it; does not modify this Region.Finds the largest contiguous area of "on" cells in this Region and returns it; does not modify this Region.last()Gets the last Coord in the iteration order, or (-1,-1) if this Region is empty.intmirrorY()Returns a new Region that has been mirrored along the rightmost edge, parallel to the y-axis.Modifies this Region so the only cells that will be "on" have a neighbor downwards when this is called.Modifies this Region so the only cells that will be "on" have a neighbor downwards and to the left when this is called.Modifies this Region so the only cells that will be "on" have a neighbor downwards and to the right when this is called.Modifies this Region so the only cells that will be "on" have a neighbor to the left when this is called.Modifies this Region so the only cells that will be "on" have a neighbor to the right when this is called.Modifies this Region so the only cells that will be "on" have a neighbor upwards when this is called.Modifies this Region so the only cells that will be "on" have a neighbor upwards and to the left when this is called.Modifies this Region so the only cells that will be "on" have a neighbor upwards and to the right when this is called.not()Negates this Region, turning "on" to "off" and "off" to "on."Like andNot, but subtracts this Region from other and stores the result in this Region, without mutating other.nth(int index) static Regionof(int width, int height, long... data) Constructs a Region using a vararg for data.Union of two Regions, assigning the result into this Region.voidperceptualHashQuick(long[] into, int[] working) Calculates a perceptual hash for this Region using a method that is only precise for some sizes of Region; it writes a result to into, and uses working as a temporary buffer.static longrandomInterleave(com.github.tommyettinger.random.EnhancedRandom 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(com.github.tommyettinger.random.EnhancedRandom rng, int size) randomRegion(com.github.tommyettinger.random.EnhancedRandom rng, int size) randomScatter(com.github.tommyettinger.random.EnhancedRandom rng, int minimumDistance) Modifies this Region 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.randomScatter(com.github.tommyettinger.random.EnhancedRandom rng, int minimumDistance, int limit) Modifies this Region 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.floatfloatrefill(boolean[][] map) Reassigns this Region 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.refill(boolean[] bits, int width, int height) Reassigns this Region 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."refill(byte[][] map, int lower, int upper) Reassigns this Region 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.refill(char[][] map, char yes) Reassigns this Region 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.refill(char[][] map, char[] yes) Reassigns this Region 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.refill(float[][] map, float upperBound) Reassigns this Region with the given rectangular float array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.refill(float[][] map, float lower, float upper) Reassigns this Region with the given rectangular float array, reusing the current data storage (without extra allocations) if this.width == map.length and this.height == map[0].length.refill(float[][] map, float lowerBound, float upperBound, int scale) Reassigns this Region with the given rectangular float array, reusing the current data storage (without extra allocations) ifthis.width == map.length * scale && this.height == map[0].length * scale.refill(int[][] map, int yes) Reassigns this Region 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.refill(int[][] map, int lower, int upper) Reassigns this Region 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.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 Region will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for this Region, potentially re-allocating the internal data this uses if width and/or height are different from what they were.refill(short[][] map, int lower, int upper) Reassigns this Region 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.refill(com.github.tommyettinger.function.IntIntPredicate decider, int width, int height) Reassigns this Region with the given function to decide which positions will be "on", reusing the current data storage (without extra allocations) if this.width == width and this.height == height.refill(com.github.tommyettinger.random.EnhancedRandom random, float fraction, int width, int height) Reassigns this Region 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.refill(com.github.tommyettinger.random.EnhancedRandom random, int width, int height) Reassigns this Region 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.Reassigns this Region with the given function to decide which positions will be "on", reusing the current data storage (without extra allocations) if this.width == width and this.height == height.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.A useful method for efficiency, remake() reassigns this Region to have its contents replaced by other.remove(int x, int y) Takes another Region, called other, with potentially different size and removes its "on" cells from this Region at the given x,y offset, allowing negative x and/or y to remove only part of other in this.Takes another Region, called other, with potentially different size and removes its "on" cells from this Region at the given x,y offset, allowing negative x and/or y to remove only part of other in this.booleanbooleanremoveAll(Collection<?> c) removeCircle(Coord center, int radius) 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.removeCorners(Region buffer) 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.Turns all cells that are adjacent to the boundaries of the Region to "off".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.removeSeveral(Coord... points) removeSeveral(Iterable<Coord> points) resizeAndEmpty(int width, int height) If this Region has the same width and height passed as parameters, this acts the same asempty(), makes no allocations, and returns this Region 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 Region with its new width and height, with all contents "off".booleanretainAll(Collection<?> c) retract()Takes the "on" cells in this Region 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.retract(int amount) Takes the "on" cells in this Region and retracts them by one cell in the 4 orthogonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.Takes the "on" cells in this Region and retracts them by one cell in the 4 orthogonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.Takes the "on" cells in this Region 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.Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell that was orthogonally or diagonally adjacent to an "off" cell into an "off" cell.retract8way(int amount) Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal or diagonal distance to an "off" cell into an "off" cell.retract8way(int amount, Region temp) Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal or diagonal distance to an "off" cell into an "off" cell.retract8way(Region temp) Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell that was orthogonally or diagonally adjacent to an "off" cell into an "off" cell.Region[]retractSeries(int amount) Creates an array ofamountRegions, each a copy of this Region that has beenretract()-ed by a progressively greater amount starting at 1 and ending at a retraction ofamountfrom the edges.Region[]retractSeries8way(int amount) Creates an array ofamountRegions, each a copy of this Region that has beenretract8way()-ed by a progressively greater amount starting at 1 and ending at a retraction ofamountfrom the edges.com.github.tommyettinger.ds.ObjectList<Region> Creates an ObjectList of Regions, each a copy of this Region that has been retracted by a progressively greater amount starting at 1 and ending at the smallest possible non-empty Region that can produce.com.github.tommyettinger.ds.ObjectList<Region> Creates an ObjectList of Regions, each a copy of this Region that has beenretract8way()-ed by a progressively greater amount starting at 1 and ending at the smallest possible non-empty Region that can produce.Coord[]separatedBlue(float fraction) Gets a Coord array from the "on" contents of this Region, using a quasi-random scattering of chosen cells with a count that matches the givenfractionof the total amount of "on" cells in this.Coord[]separatedBlue(float fraction, int limit) Gets a Coord array from the "on" contents of this Region, using a quasi-random scattering of chosen cells with a count that matches the givenfractionof the total amount of "on" cells in this.Coord[]separatedPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance) Gets all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned array.Coord[]separatedPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance, int limit) Gets all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned array.separatedRegionBlue(float fraction) Modifies this Region so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()matches the givenfractionof the total amount of "on" cells in this.separatedRegionBlue(float fraction, int limit) Modifies this Region so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()matches the givenfractionof the total amount of "on" cells in this.separatedRegionPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance) Removes all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned Region.separatedRegionPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance, int limit) Removes all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned Region.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.Sets the cell at point to on if value is true or off if value is false.show(char on, char off) Returns this Region'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.singleRandom(com.github.tommyettinger.random.EnhancedRandom rng) Gets a single random Coord from the "on" positions in this Region, or the Coord (-1,-1) if this is empty.intsingleRandomTight(com.github.tommyettinger.random.EnhancedRandom rng) intsize()A randomized flood-fill that modifies this Region so it randomly adds adjacent cells while staying inside the "on" cells ofbounds, untilsize()is equal tovolumeor there are no more cells this can expand into.spill(Region bounds, int volume, com.github.tommyettinger.random.EnhancedRandom rng, Region temp, Region temp2) A randomized flood-fill that modifies this Region so it randomly adds adjacent cells while staying inside the "on" cells ofbounds, untilsize()is equal tovolumeor there are no more cells this can expand into.A randomized flood-fill that modifies this Region so it randomly adds one adjacent cell if it can while staying inside the "on" cells ofbounds.A randomized flood-fill that modifies this Region so it randomly adds one adjacent cell if it can while staying inside the "on" cells ofbounds.com.github.tommyettinger.ds.ObjectList<Region> split()If this Region 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 ObjectList of Region, with one Region per isolated area.com.github.tommyettinger.ds.ObjectList<Region> If this Region 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 ObjectList of Region, with one Region per isolated area.A selective flood-fill that modifies this Region so it adds adjacent cells thatdeciderevaluates totruefor, if it can while staying inside the "on" cells ofbounds.A selective flood-fill that modifies this Region so it adds adjacent cells thatdeciderevaluates totruefor, if it can while staying inside the "on" cells ofbounds.A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds.A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y, z)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds.A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y, z)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds.A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds.static Regionstatic int[][]Generates a 2D int array from an array or vararg of Regions, starting at all 0 and adding 1 to the int at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.static int[][]Generates a 2D int array from a List of Regions, starting at all 0 and adding 1 to the int at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.static float[][]Generates a 2D float array from an array or vararg of Regions, starting at all 0 and adding 1 to the float at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.static float[][]Generates a 2D float array from a List of Regions, starting at all 0 and adding 1 to the float at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.static int[][]Adds to an existing 2D int array with an array or vararg of Regions, adding 1 to the int in existing at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 Regions, then it can increase the value in existing by any number between 0 and 16 in a cell.static float[][]sumIntoFloat(float[][] existing, Region... regions) Adds to an existing 2D float array with an array or vararg of Regions, adding 1 to the float in existing at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 Regions, then it can increase the value in existing by any number between 0 and 16 in a cell.static int[][]sumWeighted(Region[] regions, int[] weights) Generates a 2D int array from an array of Regions and an array of weights, starting the 2D result at all 0 and, for every Region that has that cell as "on," adding the int in the corresponding weights array at the position of that cell.static float[][]sumWeightedFloat(Region[] regions, float[] weights) Generates a 2D float array from an array of Regions and an array of weights, starting the 2D result at all 0 and, for every Region that has that cell as "on," adding the float in the corresponding weights array at the position of that cell.surface()Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell.surface(int amount) Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell.Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell.Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell.Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell.surface8way(int amount) Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell.surface8way(int amount, Region temp, Region temp2) Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell.surface8way(Region temp) Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell.Region[]surfaceSeries(int amount) Takes the "on" cells in this Region and produces amount Regions, each one a smaller and smaller result ofsurface()by 1 cell in the 4 orthogonal directions relative to the previous Region.Region[]surfaceSeries8way(int amount) Takes the "on" cells in this Region and produces amount Regions, each one a smaller and smaller result ofsurface8way()by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region.com.github.tommyettinger.ds.ObjectList<Region> Returns an ObjectList of progressively further-retracted copied surfaces of this Region.com.github.tommyettinger.ds.ObjectList<Region> Returns an ObjectList of progressively further-retracted copied surfaces of this Region.thin()Likeretract(), this reduces the width of thick areas of this Region, but thin() will not remove areas that would be identical in a subsequent call to retract(), such as if the area would be eliminated.Likeretract(), this reduces the width of thick areas of this Region, but thin() will not remove areas that would be identical in a subsequent call to retract(), such as if the area would be eliminated.thin8way()Likeretract8way(), this reduces the width of thick areas of this Region, but thin8way() will not remove areas that would be identical in a subsequent call to retract8way(), such as if the area would be eliminated.Likeretract8way(), this reduces the width of thick areas of this Region, but thin8way() will not remove areas that would be identical in a subsequent call to retract8way(), such as if the area would be eliminated.Callsthin()repeatedly, until the result is unchanged from the last call.Callsthin()repeatedly, until the result is unchanged from the last call.Callsthin8way()repeatedly, until the result is unchanged from the last call.thinFully8way(Region bufferA, Region bufferB, Region bufferC) Callsthin8way()repeatedly, until the result is unchanged from the last call.Object[]toArray()<T> T[]toArray(T[] a) char[][]toChars()Returns this Region'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 Region'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.Compresses this Region into a UTF-16 String and returns the String without modifying this Region.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.int[][]toInts(int on, int off) Returns this Region's data as a 2D int array, [width][height] in size, with "on" cells filled with the int parameter on and "off" cells with the parameter off.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).translate(int x, int y) Moves the "on" cells in this Region to the given x and y offset, removing cells that move out of bounds.Moves the "on" cells in this Region to the given x and y offset, removing cells that move out of bounds.static com.github.tommyettinger.ds.ObjectOrderedSet<Region> whichContain(int x, int y, Region... packed) static com.github.tommyettinger.ds.ObjectOrderedSet<Region> whichContain(int x, int y, Collection<Region> packed) char[][]writeChars(char[][] map, char toWrite) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the char toWrite.char[][]writeCharsInto(char[][] map, char toWrite) LikewriteChars(char[][], char), but modifiesmapin-place and returns it.char[][]writeCharsToOff(char[][] map, char filler) Returns a copy of map where if a cell is "on" in this Region, this keeps the value in map intact, and where a cell is "off", it instead writes the char filler.float[][]writeFloats(float[][] map, float toWrite) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the float toWrite.float[][]writeFloatsInto(float[][] map, float toWrite) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the float toWrite.int[][]writeInts(int[][] map, int toWrite) Returns a copy of map where if a cell is "off" in this Region, 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) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the int toWrite.short[][]writeShortsToOff(short[][] map, short filler) Returns a copy of map where if a cell is "on" in this Region, this keeps the value in map intact, and where a cell is "off", it instead writes the short filler.intxBound(boolean findSmallest) Symmetric difference (more commonly known as exclusive or, hence the name) of two Regions, assigning the result into this Region.intyBound(boolean findSmallest) 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 Region (which is this, assigning to itself).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 Region (which is this, assigning to itself).Methods inherited from interface Collection
parallelStream, removeIf, spliterator, stream, toArray
-
Field Details
-
data
public long[] data -
height
public int height -
width
public int width -
BLUE_LEVELS
A 256-element array ofRegions, each 64x64, where the first Region has an impossibly strict threshold on what points to include (it is empty), but the second has some points far apart, the third has more, and so on until the last element includes almost all points.
-
-
Constructor Details
-
Region
public Region()Constructs an empty 4x64 Region. Regions are mutable, so you can add to this with insert() or insertSeveral(), among others. You can also resize this and clear it withresizeAndEmpty(int, int), or replace its contents with those of another Region withremake(Region). -
Region
public Region(boolean[][] bits) Constructs a Region 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
-
Region
public Region(char[][] map, char yes) Constructs a Region 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"
-
Region
public Region(char[][] map, char[] yes) Constructs a Region 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"
-
Region
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 Region
-
Region
public Region(int[][] map, int yes) Constructs a Region 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"
-
Region
public Region(int[][] map, int lower, int upper) Constructs this Region 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
-
Region
public Region(byte[][] map, int lower, int upper) Constructs this Region 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
-
Region
public Region(short[][] map, int lower, int upper) Constructs this Region 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
-
Region
public Region(float[][] map, float upperBound) Constructs this Region using a float[][] (typically one generated by DijkstraMap) 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 float[][] that probably relates in some way to DijkstraMap.upperBound- upper inclusive; any float greater than this will be off, any others will be on
-
Region
public Region(float[][] map, float lowerBound, float upperBound) Constructs this Region using a float[][] (typically one generated by DijkstraMap) 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 float[][] that probably relates in some way to DijkstraMap.lowerBound- lower inclusive; any float lower than this will be off, any equal to or greater than this, but less than upper, will be onupperBound- upper exclusive; any float greater than or equal to this will be off, any floats both less than this and equal to or greater than lower will be on
-
Region
public Region(float[][] map, float lowerBound, float upperBound, int scale) Constructs this Region using a float[][] 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 float[][]; depending on scale, the Region may have different width and heightlowerBound- lower inclusive; any float lower than this will be off, any equal to or greater than this, but less than upper, will be onupperBound- upper exclusive; any float greater than or equal to this will be off, any floats 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
-
Region
public Region(boolean[] bits, int width, int height) Constructs a Region 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 Region; width * height should equal bits.lengthheight- the height of the desired Region; width * height should equal bits.length
-
Region
public Region(com.github.tommyettinger.function.IntIntPredicate decider, int width, int height) Constructs a Region with the given width and height by callingdecider's functional method on each x,y position for x from 0 (inclusive) to width (exclusive) and for y from 0 (inclusive) to height (exclusive). Ifdeciderreturns true for an x,y position, that position will be "on", otherwise it will be "off".- Parameters:
decider- a function that takes an int x and an int y and returns true if that position should be "on"width- the width of the desired Regionheight- the height of the desired Region
-
Region
Constructs a Region with the given width and height by callingINoise.getNoise(float, float)position for x from 0 (inclusive) to width (exclusive) and for y from 0 (inclusive) to height (exclusive). If this returns a float betweenlower(inclusive) andupper(exclusive) for an x,y position, that position will be "on", otherwise it will be "off".- Parameters:
noise- a noise generator that will have 2D noise queried from it with its default seedlower- inclusive lower bound on noise results that will be considered "on"; usually between -1 and 1upper- exclusive upper bound on noise results that will be considered "on"; usually between -1 and 1width- the width of the desired Regionheight- the height of the desired Region
-
Region
public Region(int width, int height) Constructor for an empty Region of the given width and height. Regions are mutable, so you can add to this with insert() or insertSeveral(), among others.- Parameters:
width- the maximum width for the Regionheight- the maximum height for the Region
-
Region
Constructor for a Region 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 Regionwidth- the maximum width for the Regionheight- the maximum height for the Region
-
Region
Constructor for a Region 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 Regionheight- the maximum height for the Regionpoints- an array or vararg of Coord to store as "on" in this Region
-
Region
Constructor for a Region 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 Regionheight- the maximum height for the Regionpoints- an array or vararg of Coord to store as "on" in this Region
-
Region
public Region(com.github.tommyettinger.random.EnhancedRandom random, int width, int height) Constructor for a random Region of the given width and height, typically assigning approximately half of the cells in this to "on" and the rest to off.- Parameters:
random- a EnhancedRandom, or a recommended subclass likeWhiskerRandomwidth- the maximum width for the Regionheight- the maximum height for the Region
-
Region
public Region(com.github.tommyettinger.random.EnhancedRandom random, float fraction, int width, int height) Constructor for a random Region 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 EnhancedRandom, per 64 cells of this Region (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 parameterrandomcan be a plainEnhancedRandom, but will be much faster and have less potential for patterns or artifacts in the output if you useWhiskerRandomor another higher-quality subclass.- Parameters:
random- a EnhancedRandom or a recommended subclass, likeWhiskerRandomfraction- between 0.0 and 1.0 (clamped), only considering a precision of 1/64.0 (0.015625) between stepswidth- the maximum width for the Regionheight- the maximum height for the Region
-
Region
Copy constructor that takes another Region 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(Region)method on the variable instead, which will, if it has the same width and height as the other Region, avoid creating garbage and quickly fill the variable with the other's contents.- Parameters:
other- another Region that will be copied into this new Region- See Also:
-
Region
public Region(long[] data2, int width, int height) Primarily for internal use, this constructor copies data2 exactly into the internal long array the new Region 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 Region are actually removed (this only matters if height is not a multiple of 64).- Parameters:
data2- a long array that is typically from another Region, and would be hard to make otherwisewidth- the width of the Region to constructheight- the height of the Region to construct
-
Region
public Region(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 Region will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for the constructed Region. 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 Region, 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 Region to constructheight- the height of the Region to construct
-
-
Method Details
-
refill
Reassigns this Region 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 Region 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 Region 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 Region- Returns:
- this for chaining
-
refill
Reassigns this Region 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 Region 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 Region 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 Region 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 Region with the given rectangular float 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 float 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 Region with the given rectangular float 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 float 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 Region with the given rectangular float 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 float[][]; depending on scale, the Region may have different width and heightlowerBound- lower inclusive; any float lower than this will be off, any equal to or greater than this, but less than upper, will be onupperBound- upper exclusive; any float greater than or equal to this will be off, any floats 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 Region 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 Region; width * height should equal bits.lengthheight- the height of the desired Region; width * height should equal bits.length- Returns:
- this for chaining
-
refill
public Region refill(com.github.tommyettinger.function.IntIntPredicate decider, int width, int height) Reassigns this Region with the given function to decide which positions will be "on", reusing the current data storage (without extra allocations) if this.width == width and this.height == height. Ifdeciderreturns true for an x,y position, that position will be "on", otherwise it will be "off".- Parameters:
decider- a function that takes an int x and an int y and returns true if that position should be "on"width- the width of the desired Regionheight- the height of the desired Region- Returns:
- this for chaining
-
refill
Reassigns this Region with the given function to decide which positions will be "on", reusing the current data storage (without extra allocations) if this.width == width and this.height == height. If this returns a float betweenlower(inclusive) andupper(exclusive) for an x,y position, that position will be "on", otherwise it will be "off".- Parameters:
noise- a noise generator that will have 2D noise queried from it with its default seedlower- inclusive lower bound on noise results that will be considered "on"; usually between -1 and 1upper- exclusive upper bound on noise results that will be considered "on"; usually between -1 and 1width- the width of the desired Regionheight- the height of the desired Region- Returns:
- this for chaining
-
resizeAndEmpty
If this Region has the same width and height passed as parameters, this acts the same asempty(), makes no allocations, and returns this Region 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 Region with its new width and height, with all contents "off". This is meant for cases where a Region may be reused effectively, but its size may not always be the same.- Parameters:
width- the width to potentially resize this Region toheight- the height to potentially resize this Region to- Returns:
- this Region, always with all contents "off", and with the height and width set.
-
refill
Reassigns this Region 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- a EnhancedRandom or a recommended subclass, likeWhiskerRandomwidth- the width of the desired Regionheight- the height of the desired Region- Returns:
- this for chaining
-
refill
public Region refill(com.github.tommyettinger.random.EnhancedRandom random, float fraction, int width, int height) Reassigns this Region 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 EnhancedRandom, per 64 cells of this Region (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 parameterrandomcan be a plainEnhancedRandom, but will be much faster and have less potential for patterns or artifacts in the output if you useWhiskerRandomor another higher-quality subclass.- Parameters:
random- a EnhancedRandom or a recommended subclass, likeWhiskerRandomfraction- between 0.0 and 1.0 (clamped), only considering a precision of 1/64.0 (0.015625) between stepswidth- the maximum width for the Regionheight- the maximum height for the Region- Returns:
- this for chaining
-
refill
Primarily for internal use, this method copies data2 into the internal long array the new Region will use, but treats data2 as having the dimensions [dataWidth][dataHeight], and uses the potentially-different dimensions [width][height] for this Region, 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 Region, 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 Region to haveheight- the height to set this Region to have
-
remake
A useful method for efficiency, remake() reassigns this Region to have its contents replaced by other. If other and this Region 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 Region 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 Regions can be key to maintaining good performance and memory usage. You often can recycle a no-longer-used Region by assigning a Region 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 Region to replace the data in this Region with- Returns:
- this for chaining
-
alterBounds
Changes the width and/or height of this Region, enlarging or shrinking starting at the edges wherex == width - 1andy == 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, Region)if you want to place one Region 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 Region that has been rotated 90 degreesturnstimes. If using y-down coordinates, then these rotations are clockwise; otherwise, they are counter-clockwise. This uses a copy because in many caseswhere the Region has non-equal width and height, the rotated version has different dimensions, and that requires allocating most of a new Region anyway. This Region 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 Region
-
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
-
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 Region'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 Region, called other, with potentially different size and inserts its "on" cells into this Region at the given x,y offset, allowing negative x and/or y to put only part of other in this.
This allocates a long array internally; to avoid that, you can useinsert(int, int, Region, Region).- 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 Region to insert- Returns:
- this for chaining
-
insert
Takes another Region, called other, with potentially different size and inserts its "on" cells into this Region at the given x,y offset, allowing negative x and/or y to put only part of other in this.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain undefined data.- 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 Region to insertbuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
insertSeveral
-
insertSeveral
-
insertSeveral
-
insertRectangle
-
insertCircle
-
remove
-
remove
-
remove
Takes another Region, called other, with potentially different size and removes its "on" cells from this Region 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. The code is identical toinsert(int, int, Region)except that where insert only adds cells, this only removes cells. Essentially, insert() is toor(Region)as remove() is toandNot(Region).
This allocates a long array internally; to avoid that, you can useremove(int, int, Region, Region).- 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 Region to remove- Returns:
- this for chaining
-
remove
Takes another Region, called other, with potentially different size and removes its "on" cells from this Region 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. The code is identical toinsert(int, int, Region)except that where insert only adds cells, this only removes cells. Essentially, insert() is toor(Region)as remove() is toandNot(Region).
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain undefined data.- 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 Region to removebuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
removeSeveral
-
removeSeveral
-
removeRectangle
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
-
allOn
-
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 Region to "off".- Returns:
- this for chaining
-
copy
Simple method that returns a newly-allocated copy of this Region; modifications to one won't change the other, and this method returns the copy while leaving the original unchanged.- Returns:
- a copy of this Region; the copy can be changed without altering the original
-
decode
public boolean[][] decode()Returns this Region'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 Region's data
-
intoChars
public char[][] intoChars(char[][] chars, char on, char off) Fills this Region's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteronand "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 Region's data
-
intoChars
public char[][] intoChars(char[][] chars, char on) Fills this Region's data into the given 2D char array, modifying it and returning it, with "on" cells filled with the char parameteronand "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 Region's data written over chars
-
toChars
public char[][] toChars(char on, char off) Returns this Region'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 Region's data
-
toChars
public char[][] toChars()Returns this Region'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 Region's data
-
show
Returns this Region'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 Region 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). -
writeCharsToOff
public char[][] writeCharsToOff(char[][] map, char filler) Returns a copy of map where if a cell is "on" in this Region, 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 Region stores an "off" cell- Returns:
- a masked copy of map, with "off" cells from this changed to filler
-
writeShortsToOff
public short[][] writeShortsToOff(short[][] map, short filler) Returns a copy of map where if a cell is "on" in this Region, 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.writeCharsToOff(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 Region stores an "off" cell- Returns:
- a masked copy of map, with "off" cells from this changed to filler
-
writeChars
public char[][] writeChars(char[][] map, char toWrite) Returns a copy of map where if a cell is "off" in this Region, 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 Region stores an "on" cell- Returns:
- a masked copy of map, with "on" cells from this changed to toWrite
-
writeInts
public int[][] writeInts(int[][] map, int toWrite) Returns a copy of map where if a cell is "off" in this Region, 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 Region stores an "on" cell- Returns:
- a masked copy of map, with "on" cells from this changed to toWrite
-
writeIntsInto
public int[][] writeIntsInto(int[][] map, int toWrite) Returns a copy of map where if a cell is "off" in this Region, 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 Region stores an "on" cell- Returns:
- map, with "on" cells from this changed to toWrite; not a copy
-
toInts
public int[][] toInts(int on, int off) Returns this Region's data as a 2D int array, [width][height] in size, with "on" cells filled with the int parameter on and "off" cells with the parameter off.- Parameters:
on- the int to use for "on" cellsoff- the int to use for "off" cells- Returns:
- a 2D int array that represents this Region's data
-
writeFloats
public float[][] writeFloats(float[][] map, float toWrite) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the float toWrite.- Parameters:
map- a 2D float array that will not be modifiedtoWrite- the float to use where this Region stores an "on" cell- Returns:
- an altered copy of map, with "on" cells from this changed to toWrite
-
writeFloatsInto
public float[][] writeFloatsInto(float[][] map, float toWrite) Returns a copy of map where if a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the float toWrite. Modifies map in-place, unlikewriteFloats(float[][], float).- Parameters:
map- a 2D float array that will be modifiedtoWrite- the float to use where this Region stores an "on" cell- Returns:
- map, with "on" cells from this changed to toWrite; not a copy
-
writeCharsInto
public char[][] writeCharsInto(char[][] map, char toWrite) LikewriteChars(char[][], char), but modifiesmapin-place and returns it. If a cell is "off" in this Region, this keeps the value in map intact, and where a cell is "on", it instead writes the char toWrite. Modifies map in-place, unlikewriteChars(char[][], char).- Parameters:
map- a 2D char array that will be modifiedtoWrite- the char to use where this Region stores an "on" cell- Returns:
- map, with "on" cells from this changed to toWrite; not a copy
-
or
-
and
Intersection of two Regions, assigning the result into this Region. Any cell that is "on" in both Regions will be kept "on" in this Region, but all other cells will be made "off."- Parameters:
other- another Region that will not be modified- Returns:
- this, after modification, for chaining
-
andWrapping64
Intersection of two Regions, assigning the result into this Region, 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 Region. Any cell that is "on" in both Regions (treating other as tiling) will be kept "on" in this Region, but all other cells will be made "off."- Parameters:
other- another Region 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 Regions, assigning the result into this Region. Any cell that is "on" in this Region and "off" in other will be kept "on" in this Region, but all other cells will be made "off."- Parameters:
other- another Region that will not be modified- Returns:
- this, after modification, for chaining
- See Also:
-
notAnd
-
xor
Symmetric difference (more commonly known as exclusive or, hence the name) of two Regions, assigning the result into this Region. 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 Regions (not "on" in both, or "off" in both).- Parameters:
other- another Region that will not be modified- Returns:
- this, after modification, for chaining
-
not
Negates this Region, turning "on" to "off" and "off" to "on."- Returns:
- this, after modification, for chaining
-
translate
Moves the "on" cells in this Region to the given x and y offset, removing cells that move out of bounds.- Parameters:
x- the x offset to translate by; can be negativey- the y offset to translate by; can be negative- Returns:
- this for chaining
-
translate
Moves the "on" cells in this Region to the given x and y offset, removing cells that move out of bounds.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- Parameters:
x- the x offset to translate by; can be negativey- the y offset to translate by; can be negativebuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
insertTranslation
Adds to this Region 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
-
insertTranslation
Adds to this Region 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.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- Parameters:
x- the x offset to translate by; can be negativey- the y offset to translate by; can be negativebuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- 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 Region (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
-
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 Region (which is this, assigning to itself).
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- 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 negativebuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
connect
Takes the pairs of "on" cells in this Region 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 Region 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 Region 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.- Returns:
- this for chaining
-
connectLines
Takes the pairs of "on" cells in this Region 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 overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- Parameters:
buffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
thin
Likeretract(), this reduces the width of thick areas of this Region, 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
-
thin
Likeretract(), this reduces the width of thick areas of this Region, 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).
This overload allows reusing temporary "buffer" Regions to avoid allocation. Each buffer Region should be the same size as this one; otherwise some allocation is still needed.- Parameters:
bufferA- a temporary Region that should be the same size as this RegionbufferB- a temporary Region that should be the same size as this RegionbufferC- a temporary Region that should be the same size as this Region- 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 Region 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
-
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 Region 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 uses 4-way adjacency. This overload allows reusing temporary "buffer" Regions to avoid allocation. Each buffer Region should be the same size as this one; otherwise some allocation is still needed.- Parameters:
bufferA- a temporary Region that should be the same size as this RegionbufferB- a temporary Region that should be the same size as this RegionbufferC- a temporary Region that should be the same size as this Region- Returns:
- this for chaining
-
thin8way
Likeretract8way(), this reduces the width of thick areas of this Region, 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
-
thin8way
Likeretract8way(), this reduces the width of thick areas of this Region, 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 uses 8-way adjacency. This overload allows reusing temporary "buffer" Regions to avoid allocation. Each buffer Region should be the same size as this one; otherwise, some allocation is still needed.- Parameters:
bufferA- a temporary Region that should be the same size as this RegionbufferB- a temporary Region that should be the same size as this RegionbufferC- a temporary Region that should be the same size as this Region- 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 Region 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
-
thinFully8way
Callsthin8way()repeatedly, until the result is unchanged from the last call. Consider using the idiomexpand8way(bufferA).retract(bufferA).thinFully8way(bufferA, bufferB, bufferC)to help change a possibly-strange appearance when the Region 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 uses 8-way adjacency. This overload allows reusing temporary "buffer" Regions to avoid allocation. Each buffer Region should be the same size as this one; otherwise, some allocation is still needed.- Parameters:
bufferA- a temporary Region that should be the same size as this RegionbufferB- a temporary Region that should be the same size as this RegionbufferC- a temporary Region that should be the same size as this Region- 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
public static long approximateBits(com.github.tommyettinger.random.EnhancedRandom random, int bitCount) 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 EnhancedRandom, which is recommended to be a subclass likeWhiskerRandom. 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 parameterrandomcan be a plainEnhancedRandom, but will be much faster and have less potential for patterns or artifacts in the output if you useWhiskerRandomor another higher-quality subclass.- Parameters:
random- a EnhancedRandom or a recommended subclass, likeWhiskerRandombitCount- 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
public static long randomInterleave(com.github.tommyettinger.random.EnhancedRandom 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.
Not exactly general-use; meant for generating data for Region.- 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 Region 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 operates in bulk on up to 64 cells at a time. This overload allocates an array the same size as the one used internally in this Region. To avoid allocating anything, you can reuse a Region the same size as this one and pass it toexpand(Region).- Returns:
- this for chaining
-
expand
Takes the "on" cells in this Region 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 operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
expand
Takes the "on" cells in this Region and expands them byamountcells 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 operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,expand(int, Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call expand(int) repeatedly.- Returns:
- this for chaining
-
expand
Takes the "on" cells in this Region and expands them byamountcells 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 operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
expandSeries
Takes the "on" cells in this Region and producesamountRegions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous Region, 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 Regions with progressively greater expansions, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is expanded by 1 relative to the last
-
expandSeriesToLimit
Returns a new ObjectList of Region where each item is a progressively more and moreexpand()-ed copy of this Region, until ending where the entire Region is "on" cells.- Returns:
- a new ObjectList of copies of this Region, each expanded more and more until every cell is "on"
-
fringe
Takes the "on" cells in this Region and expands them by one cell in the 4 orthogonal directions, producing a diamond 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 Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,fringe(Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call fringe() repeatedly.- Returns:
- this for chaining
-
fringe
Takes the "on" cells in this Region and expands them by one cell in the 4 orthogonal directions, producing a diamond 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 Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
fringe
Takes the "on" cells in this Region 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 Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,fringe(Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call fringe() repeatedly.- Parameters:
amount- how thick the bordering area should be- Returns:
- this for chaining
-
fringe
Takes the "on" cells in this Region 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 Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This overload of fringe allows taking atempandtemp2Region that should be the same size as this Region, and won't allocate by modifying temp and temp2 in-place. While temp, if non-null, will reliably contain the same contents as this Region before this method call, temp2 won't have any guarantee. All values in temp2 will be eliminated, so it really should be considered temporary. If temp or temp2 is a different size from this Region, some memory will be allocated; allocation will also occur if any of temp or temp2 is null.- Parameters:
amount- how thick the bordering area should betemp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as thistemp2- another Region that will be erased and replaced with undefined contents; should be the same size as this- Returns:
- this for chaining
-
fringeSeries
Takes the "on" cells in this Region and produces amount Regions, each one expanded by 1 cell in the 4 orthogonal directions relative to the previous Region, making each "on" cell take up a diamond-shaped area. After producing the expansions, this removes the previous Region from the next Region 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 Regions with progressively greater expansions without the cells of this Region, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is a 1-depth fringe pushed further out from this
-
fringeSeriesToLimit
Returns an ObjectList of progressively further-expanded copied fringes of this Region. This works likeexpandSeriesToLimit(), and produces the same number of Region copies as that method, but removes everything but the edge of each copy. Uses 4-way adjacency, adding only orthogonally-adjacent cells.- Returns:
- a new ObjectList of copies of this Region, each expanded more and more until expansion can't add cells, and with everything but the latest expansion removed
-
retract
Takes the "on" cells in this Region 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 operates in bulk on up to 64 cells at a time. This overload allocates an array the same size as the one used internally in this Region.- Returns:
- this for chaining
-
retract
Takes the "on" cells in this Region 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 operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
retract
Takes the "on" cells in this Region and retracts them by one cell in the 4 orthogonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.
This operates in bulk on up to 64 cells at a time. This allocates and discards a temporary Region with the same size as this one.- Returns:
- this for chaining
-
retract
Takes the "on" cells in this Region and retracts them by one cell in the 4 orthogonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal distance to an "off" cell into an "off" cell.
This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
retractSeries
Creates an array ofamountRegions, each a copy of this Region that has beenretract()-ed by a progressively greater amount starting at 1 and ending at a retraction ofamountfrom the edges. This method allocates multiple copied Regions and returns most of them in an array.- Parameters:
amount- how many Region copies should be in the returned array; should be non-negative- Returns:
- a new Region array containing progressively more and more retract()-ed copies of this Region
-
retractSeriesToLimit
Creates an ObjectList of Regions, each a copy of this Region that has been retracted by a progressively greater amount starting at 1 and ending at the smallest possible non-empty Region that can produce.- Returns:
- a new Region ObjectList containing progressively more and more retract()-ed copies of this Region
-
surface
Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell. This uses 4-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe()but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,surface(Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call surface() repeatedly.- Returns:
- this for chaining
-
surface
Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell. This uses 4-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe()but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
surface
Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell. This uses 4-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe(int)but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This overload allocates a temporary buffer Region;surface(int, Region, Region)does not.- Parameters:
amount- how thick the bordering area should be- Returns:
- this for chaining
-
surface
Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell. This uses 4-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe(int)but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This overload of surface allows taking atempandtemp2Region that should be the same size as this Region, and won't allocate by modifying temp and temp2 in-place. While temp, if non-null, will reliably contain the same contents as this Region before this method call, temp2 won't have any guarantee. All values in temp2 will be eliminated, so it really should be considered temporary. If temp or temp2 is a different size from this Region, some memory will be allocated; allocation will also occur if any of temp or temp2 is null.- Parameters:
amount- how thick the bordering area should betemp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as thistemp2- another Region that will be erased and replaced with undefined contents; should be the same size as this- Returns:
- this for chaining
-
surfaceSeries
Takes the "on" cells in this Region and produces amount Regions, each one a smaller and smaller result ofsurface()by 1 cell in the 4 orthogonal directions relative to the previous Region. After producing the expansions, this removes the previous Region from the next Region in the array, making each "surface" in the series have 1 "thickness," which can be useful for finding which layer of surfacing a cell lies in. This returns an array of Regions with progressively smaller perimeters taken from the cells of this Region, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is a 1-depth fringe pushed further out from this
-
surfaceSeriesToLimit
Returns an ObjectList of progressively further-retracted copied surfaces of this Region. This works likeretractSeriesToLimit(), but produces one more Region copy than that method, and only retains the changed surface of the just-retracted area. This uses 4-way adjacency.- Returns:
- a new ObjectList of copies of this Region, each retracted more and more until only a surface is left, and with everything but the latest change removed from each copy
-
expand8way
Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell take up a 3x3 square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This operates in bulk on up to 64 cells at a time. This overload allocates an array the same size as the one used internally in this Region. To avoid allocating anything, you can reuse a Region the same size as this one and pass it toexpand8way(Region).- Returns:
- this for chaining
-
expand8way
Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell take up a 3x3 square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
expand8way
Takes the "on" cells in this Region and expands them byamountcells in the 8 orthogonal and diagonal directions, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This operates in bulk on up to 64 cells at a time. This overload allocates an array the same size as the one used internally in this Region. To avoid allocating anything, you can reuse a Region the same size as this one and pass it toexpand8way(int, Region).- Parameters:
amount- how thick the bordering area should be- Returns:
- this for chaining
-
expand8way
Takes the "on" cells in this Region and expands them byamountcells in the 8 orthogonal and diagonal directions, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then).
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
amount- how thick the bordering area should betemp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
expandSeries8way
Takes the "on" cells in this Region and producesamountRegions, each one expanded by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region, making each "on" cell take up a square-shaped area that may overlap with other "on" cells (which is just a normal "on" cell then). This returns an array of Regions with progressively greater expansions, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is expanded by 1 relative to the last
-
expandSeriesToLimit8way
Returns a new ObjectList of Region where each item is a progressively more and moreexpand8way()-ed copy of this Region, until just before the entire Region is "on" cells.- Returns:
- a new ObjectList of copies of this Region, each expanded more and more until expansion can't add cells
-
fringe8way
Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, producing a square shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (8-way) of an "on" cell. This method is similar tosurface8way(), but surface finds cells inside the current Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,fringe8way(Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call fringe8way() repeatedly.- Returns:
- this for chaining
-
fringe8way
Takes the "on" cells in this Region and expands them by one cell in the 8 orthogonal and diagonal directions, producing a square shape, then removes the original area before expansion, producing only the cells that were "off" in this and within 1 cell (8-way) of an "on" cell. This method is similar tosurface8way(), but surface finds cells inside the current Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
fringe8way
Takes the "on" cells in this Region and expands them by amount cells in the 8 orthogonal and diagonal directions (iteratively, producing a square shape), then removes the original area before expansion, producing only the cells that were "off" in this and within amount cells (8-way) of an "on" cell. This method is similar tosurface8way(), but surface finds cells inside the current Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,fringe8way(int, Region, Region), that takes reusable buffer Regions to avoid allocations; it can be preferable if you intend to call fringe8way() repeatedly.- Parameters:
amount- how thick the bordering area should be- Returns:
- this for chaining
-
fringe8way
Takes the "on" cells in this Region and expands them by amount cells in the 8 orthogonal and diagonal directions (iteratively, producing a square shape), then removes the original area before expansion, producing only the cells that were "off" in this and withinamountcells (8-way) of an "on" cell. This method is similar tosurface8way(), but surface finds cells inside the current Region, while fringe finds cells outside it.
This operates in bulk on up to 64 cells at a time. This overload of fringe8way allows taking atempandtemp2Region that should be the same size as this Region, and won't allocate by modifying temp and temp2 in-place. While temp, if non-null, will reliably contain the same contents as this Region before this method call, temp2 won't have any guarantee. All values in temp2 will be eliminated, so it really should be considered temporary. If temp or temp2 is a different size from this Region, some memory will be allocated; allocation will also occur if any of temp or temp2 is null.- Parameters:
amount- how thick the bordering area should betemp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as thistemp2- another Region that will be erased and replaced with undefined contents; should be the same size as this- Returns:
- this for chaining
-
fringeSeries8way
Takes the "on" cells in this Region and produces amount Regions, each one expanded by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region, making each "on" cell take up a square-shaped area. After producing the expansions, this removes the previous Region from the next Region 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 Regions with progressively greater expansions without the cells of this Region, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is a 1-depth fringe pushed further out from this
-
fringeSeriesToLimit8way
Returns an ObjectList of progressively further-expanded copied fringes of this Region. This works likeexpandSeriesToLimit8way(), and produces the same number of Region copies as that method, but removes everything but the edge of each copy. Uses 8-way adjacency, adding orthogonally- and diagonally-adjacent cells.- Returns:
- a new ObjectList of copies of this Region, each expanded more and more until expansion can't add cells, and with everything but the latest expansion removed
-
retract8way
Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell that was orthogonally or diagonally adjacent to an "off" cell into an "off" cell.
This operates in bulk on up to 64 cells at a time. This overload allocates an array the same size as the one used internally in this Region. To avoid allocating anything, you can reuse a Region the same size as this one and pass it toretract8way(Region).- Returns:
- this for chaining
-
retract8way
Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, making each "on" cell that was orthogonally or diagonally adjacent to an "off" cell into an "off" cell.
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
retract8way
Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal or diagonal distance to an "off" cell into an "off" cell.
This operates in bulk on up to 64 cells at a time. This allocates and discards a temporary Region with the same size as this one.- Returns:
- this for chaining
-
retract8way
Takes the "on" cells in this Region and retracts them by one cell in the 8 orthogonal and diagonal directions, doing this iterativelyamounttimes, making each "on" cell that was within amount orthogonal or diagonal distance to an "off" cell into an "off" cell.
This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- a temporary Region that should be the same size as this one- Returns:
- this for chaining
-
retractSeries8way
Creates an array ofamountRegions, each a copy of this Region that has beenretract8way()-ed by a progressively greater amount starting at 1 and ending at a retraction ofamountfrom the edges. This method allocates multiple copied Regions and returns most of them in an array.- Parameters:
amount- how many Region copies should be in the returned array; should be non-negative- Returns:
- a new Region array containing progressively more and more retract()-ed copies of this Region
-
retractSeriesToLimit8way
Creates an ObjectList of Regions, each a copy of this Region that has beenretract8way()-ed by a progressively greater amount starting at 1 and ending at the smallest possible non-empty Region that can produce.- Returns:
- a new Region ObjectList containing progressively more and more retract8way()-ed copies of this Region
-
surface8way
Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell. This uses 8-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe8way()but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This method allocates and discards a temporary copy of this Region. There is an overload of this method,surface8way(Region), that takes a reusable buffer Region to avoid allocations; it can be preferable if you intend to call surface8way() repeatedly.- Returns:
- this for chaining
-
surface8way
Takes the "on" cells in this Region and turns them "off" if they aren't adjacent to an existing "off" cell. This uses 8-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe()but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This overload takes a temporary Regiontempthat should be the same size as this Region. If temp is non-null, it will be cleared and receive the contents of this Region before this method call.- Parameters:
temp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
surface8way
Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell. This uses 8-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe8way(int)but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This overload allocates a temporary buffer Region;surface8way(int, Region, Region)does not.- Parameters:
amount- how thick the bordering area should be- Returns:
- this for chaining
-
surface8way
Takes the "on" cells in this Region and turns them "off" if they aren't withinamountdistance of an existing "off" cell. This uses 8-way adjacency, and will never add "on" cells to the Region (it can only remove them or leave them as-is). This method acts likefringe8way(int)but only produces "on" cells where there were "on" cells at the edge of this Region's existing "on" cells.
This operates in bulk on up to 64 cells at a time. This overload of surface8way allows taking atempandtemp2Region that should be the same size as this Region, and won't allocate by modifying temp and temp2 in-place. While temp, if non-null, will reliably contain the same contents as this Region before this method call, temp2 won't have any guarantee. All values in temp2 will be eliminated, so it really should be considered temporary. If temp or temp2 is a different size from this Region, some memory will be allocated; allocation will also occur if any of temp or temp2 is null.- Parameters:
amount- how thick the bordering area should betemp- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as thistemp2- another Region that will be erased and replaced with undefined contents; should be the same size as this- Returns:
- this for chaining
-
surfaceSeries8way
Takes the "on" cells in this Region and produces amount Regions, each one a smaller and smaller result ofsurface8way()by 1 cell in the 8 orthogonal and diagonal directions relative to the previous Region. After producing the expansions, this removes the previous Region from the next Region in the array, making each "surface" in the series have 1 "thickness," which can be useful for finding which layer of surfacing a cell lies in. This returns an array of Regions with progressively smaller perimeters taken from the cells of this Region, and does not modify this Region.
This operates in bulk on up to 64 cells at a time. This method allocates multiple copied Regions and returns most of them in an array.- Returns:
- an array of new Regions, length == amount, where each one is a 1-depth fringe pushed further out from this
-
surfaceSeriesToLimit8way
Returns an ObjectList of progressively further-retracted copied surfaces of this Region. This works likeretractSeriesToLimit8way(), but produces one more Region copy than that method, and only retains the changed surface of the just-retracted area. This uses 8-way adjacency.- Returns:
- a new ObjectList of copies of this Region, each retracted more and more until only a surface is left, and with everything but the latest change removed from each copy
-
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(), 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.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- Parameters:
bounds- the set of "on" cells that limits where this can expand intobuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- 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
-
flood
Likeexpand(int), but limits expansion to the "on" cells ofbounds. Repeatedly expands in all orthogonal 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.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate. After the call, the contents ofbufferwill be undefined.- Parameters:
bounds- the set of "on" cells that limits where this can expand intoamount- how far to expand this outward by, in cellsbuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this, after expanding, for chaining
-
floodSeries
Repeatedly callsflood(Region)amounttimes and returns the intermediate steps in a Region array of sizeamount. Doesn't modify this Region, 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 fillsboundsas 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 Region,
amountin size, containing larger and larger expansions of this
-
floodSeriesToLimit
Repeatedly generates new Regions, each one cell expanded in 4 directions from the previous Region and staying inside the "on" cells ofbounds, until it can't expand any more. Returns an ObjectList of the Region steps this generated; this list does not include this Region (or any unmodified copy of this Region), and this method does not modify it.- Parameters:
bounds- the set of "on" cells that this will attempt to fill in steps- Returns:
- an ObjectList of steps from one
flood(Region)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(), 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.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate, and after the call,bufferwill contain the previous contents of this Region.- Parameters:
bounds- the set of "on" cells that limits where this can expand intobuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- 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
-
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.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate. After the call, the contents ofbufferwill be undefined.- Parameters:
bounds- the set of "on" cells that limits where this can expand intoamount- how far to expand this outward by, in cellsbuffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this, after expanding, for chaining
-
floodSeries8way
Repeatedly callsflood8way(Region)amounttimes and returns the intermediate steps in a Region array of sizeamount. Doesn't modify this Region, 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 fillsboundsas 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 Region,
amountin size, containing larger and larger expansions of this
-
floodSeriesToLimit8way
Repeatedly generates new Regions, each one cell expanded in 8 directions from the previous Region and staying inside the "on" cells ofbounds, until it can't expand anymore. Returns an ObjectList of the Region steps this generated; this list does not include this Region (or any unmodified copy of this Region), and this method does not modify it.- Parameters:
bounds- the set of "on" cells that this will attempt to fill in steps- Returns:
- an ObjectList of steps from one
flood8way(Region)call to possibly many chained after it
-
splash
A randomized flood-fill that modifies this Region so it randomly adds one adjacent cell if it can while staying inside the "on" cells ofbounds. This Region 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, stepping one-cell-at-a-time instead of howspill(Region, int, EnhancedRandom)fills a whole volume.
This overload allocates a Region used bysplash(Region, EnhancedRandom, Region).- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisrng- a EnhancedRandom, or a recommended subclass likeWhiskerRandom- Returns:
- this, after expanding randomly once, for chaining
-
splash
public Region splash(Region bounds, com.github.tommyettinger.random.EnhancedRandom rng, Region temp) A randomized flood-fill that modifies this Region so it randomly adds one adjacent cell if it can while staying inside the "on" cells ofbounds. This Region 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, stepping one-cell-at-a-time instead of howspill(Region, int, EnhancedRandom)fills a whole volume.
This overload is just like the one that doesn't take a temp Region, but it can avoid allocating a new Region if you have one with the same size as this, to use as working space.- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisrng- a EnhancedRandom, or a recommended subclass likeWhiskerRandomtemp- another Region that will be cleared and used as a temporary buffer; optimally the same size as this- Returns:
- this, after expanding randomly once, for chaining
-
spill
A randomized flood-fill that modifies this Region so it randomly adds adjacent cells while staying inside the "on" cells ofbounds, untilsize()is equal tovolumeor there are no more cells this can expand into. This Region 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.
This method allocates two temporary Regions used byspill(Region, int, EnhancedRandom, Region, Region).- Parameters:
bounds- this Region will only expand to cells that are "on" in bounds; bounds should overlap with thisvolume- the maximumsize()this Region can reach before this stops expandingrng- a EnhancedRandom, or a recommended subclass likeWhiskerRandom- Returns:
- this, after expanding randomly, for chaining
-
spill
public Region spill(Region bounds, int volume, com.github.tommyettinger.random.EnhancedRandom rng, Region temp, Region temp2) A randomized flood-fill that modifies this Region so it randomly adds adjacent cells while staying inside the "on" cells ofbounds, untilsize()is equal tovolumeor there are no more cells this can expand into. This Region 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.
This overload is just like the one that doesn't take a temp Region, but it can avoid allocating new Regions if you have two with the same size as this, to use as working space.- Parameters:
bounds- this Region will only expand to cells that are "on" in bounds; bounds should overlap with thisvolume- the maximumsize()this Region can reach before this stops expandingrng- a EnhancedRandom, or a recommended subclass likeWhiskerRandomtemp- another Region that will be cleared and used as a temporary buffer; optimally the same size as thistemp2- another Region that will be cleared and used as a temporary buffer; optimally the same size as this- Returns:
- this, after expanding randomly, for chaining
-
stir
A selective flood-fill that modifies this Region so it adds adjacent cells thatdeciderevaluates totruefor, if it can while staying inside the "on" cells ofbounds. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. Thedecideris often a lambda that calls anINoisetype's 2D or 3D noise methods and compares to a threshold. If using 3D noise, changingzbetween calls will usually allow all cells to eventually be reached, but this can't be guaranteed, especially for extreme thresholds.
This only calls the decider'sIntIntPredicate.test(int, int)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload allocates a Region used bystir(Region, IntIntPredicate, Region).- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisdecider- a function that takes two ints (x, y) and returns true if that position should be kept- Returns:
- this, after expanding to adjacent cells where decider returned true, for chaining
-
stir
public Region stir(Region bounds, com.github.tommyettinger.function.IntIntPredicate decider, Region temp) A selective flood-fill that modifies this Region so it adds adjacent cells thatdeciderevaluates totruefor, if it can while staying inside the "on" cells ofbounds. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. Thedecideris often a lambda that calls anINoisetype's 2D or 3D noise methods and compares to a threshold. If using 3D noise, changingzbetween calls will usually allow all cells to eventually be reached, but this can't be guaranteed, especially for extreme thresholds.
This only calls the decider'sIntIntPredicate.test(int, int)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload is just like the one that doesn't take a temp Region, but it can avoid allocating a new Region if you have one with the same size as this, to use as working space.- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisdecider- a function that takes two ints (x, y) and returns true if that position should be kepttemp- another Region that will be cleared and used as a temporary buffer; optimally the same size as this- Returns:
- this, after expanding to adjacent cells where decider returned true, for chaining
-
stir
A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. Because this requests 2D noise, unless the noise has its seed change between calls (making each call totally and randomly different), some areas will usually not be possible to fill with typical bounds (ones that don't just accept all noise as in-bounds). The result from each call to getNoise() should be between -1.0 and 1.0, so both bounds are typically in that range or just outside it (to allow all low values or all high values).
This only calls noise'sINoise.getNoise(float, float)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload allocates a Region used bystir(Region, IntIntPredicate, Region).- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisnoise- an INoise that will have itsINoise.getNoise(float, float)method called per adjacent celllowerBound- usually between -1 and 1; if a result from noise at a cell is less than lowerBound, that cell won't be addedupperBound- usually between -1 and 1; if a result from noise at a cell is greater than or equal to upperBound, that cell won't be added- Returns:
- this, after expanding to adjacent cells where the noise was within range, for chaining
-
stir
A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. Because this requests 2D noise, unless the noise has its seed change between calls (making each call totally and randomly different), some areas will usually not be possible to fill with typical bounds (ones that don't just accept all noise as in-bounds). The result from each call to getNoise() should be between -1.0 and 1.0, so both bounds are typically in that range or just outside it (to allow all low values or all high values).
This only calls noise'sINoise.getNoise(float, float)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload is just like the one that doesn't take a temp Region, but it can avoid allocating a new Region if you have one with the same size as this, to use as working space.- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisnoise- an INoise that will have itsINoise.getNoise(float, float)method called per adjacent celllowerBound- usually between -1 and 1; if a result from noise at a cell is less than lowerBound, that cell won't be addedupperBound- usually between -1 and 1; if a result from noise at a cell is greater than or equal to upperBound, that cell won't be addedtemp- another Region that will be cleared and used as a temporary buffer; optimally the same size as this- Returns:
- this, after expanding to adjacent cells where the noise was within range, for chaining
-
stir
A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y, z)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds. This allows specifying the z parameter here. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. This requests 3D noise from noise, and the z parameter can change between calls; this can allow the noise to gradually change over multiple calls or multiple frames, which could allow spaces that previously couldn't be filled to become fillable. The result from each call to getNoise() should be between -1.0 and 1.0, so both bounds are typically in that range or just outside it (to allow all low values or all high values).
This only calls noise'sINoise.getNoise(float, float, float)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload allocates a Region used bystir(Region, IntIntPredicate, Region).- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisnoise- an INoise that will have itsINoise.getNoise(float, float, float)method called per adjacent cellz- the third parameter to be passed to getNoise()lowerBound- usually between -1 and 1; if a result from noise at a cell is less than lowerBound, that cell won't be addedupperBound- usually between -1 and 1; if a result from noise at a cell is greater than or equal to upperBound, that cell won't be added- Returns:
- this, after expanding to adjacent cells where the noise was within range, for chaining
-
stir
public Region stir(Region bounds, INoise noise, float z, float lowerBound, float upperBound, Region temp) A selective flood-fill that modifies this Region so it adds adjacent cells wherenoise.getNoise(x, y, z)evaluates betweenlowerBound(inclusive) andupperBound(exclusive), if it can while staying inside the "on" cells ofbounds. This allows specifying the z parameter here. This Region 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, stepping only to adjacent cells instead of howspill(Region, int, EnhancedRandom)fills a whole volume, or howsplash(Region, EnhancedRandom)only steps to one random cell. This requests 3D noise from noise, and the z parameter can change between calls; this can allow the noise to gradually change over multiple calls or multiple frames, which could allow spaces that previously couldn't be filled to become fillable. The result from each call to getNoise() should be between -1.0 and 1.0, so both bounds are typically in that range or just outside it (to allow all low values or all high values).
This only calls noise'sINoise.getNoise(float, float, float)method on cells adjacent to "on" cells in this that are also withinbounds.
This overload is just like the one that doesn't take a temp Region, but it can avoid allocating a new Region if you have one with the same size as this, to use as working space.- Parameters:
bounds- this Region will only expand to a cell that is "on" in bounds; bounds should overlap with thisnoise- an INoise that will have itsINoise.getNoise(float, float, float)method called per adjacent cellz- the third parameter to be passed to getNoise()lowerBound- usually between -1 and 1; if a result from noise at a cell is less than lowerBound, that cell won't be addedupperBound- usually between -1 and 1; if a result from noise at a cell is greater than or equal to upperBound, that cell won't be addedtemp- another Region that will be cleared and used as a temporary buffer; optimally the same size as this- Returns:
- this, after expanding to adjacent cells where the noise was within range, 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
-
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 Region 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 ObjectList of Region, with one Region 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:
Region floors = new Region(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<Region> 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 a room and a corridor are adjacent. This technique is used with some enhancements in the RoomFinder class.- Returns:
- an ObjectList containing each unconnected area from packed as a Region element
-
split8way
If this Region 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 ObjectList of Region, with one Region 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:
Region floors = new Region(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<Region> 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 a room and a corridor are adjacent. This technique is used with some enhancements in the RoomFinder class.- Returns:
- an ObjectList containing each unconnected area from packed as a Region element
-
largestPart
Finds the largest contiguous area of "on" cells in this Region and returns it; does not modify this Region. 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 Region 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 Region that corresponds to the largest contiguous sub-region of "on" cells in this.
-
largestPart8way
Finds the largest contiguous area of "on" cells in this Region and returns it; does not modify this Region. 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 Region 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 Region that corresponds to the largest contiguous sub-region of "on" cells in this.
-
neighborUp
Modifies this Region 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 Region 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 Region 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 Region 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 Region 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 Region 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 Region 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 Region 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 Region 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 Region; its size does not have to match this Region's size- Returns:
- true if this shares any "on" cells with other
-
whichContain
-
whichContain
public static com.github.tommyettinger.ds.ObjectOrderedSet<Region> whichContain(int x, int y, Collection<Region> packed) -
appendContaining
public static Collection<Region> appendContaining(Collection<Region> into, int x, int y, Region... packed) Tries to look up the position x,y in each Region in packed; each Region that contains that x,y point is appended into the Collectioninto.- Parameters:
into- a Collection of Region that will be modified if this succeedsx- the x-coordinate to look upy- the y-coordinate to look uppacked- the array or varargs of Region to try to look up the given position in- Returns:
into, potentially modified
-
appendContaining
public static Collection<Region> appendContaining(Collection<Region> into, int x, int y, Collection<Region> packed) Tries to look up the position x,y in each Region in packed; each Region that contains that x,y point is appended into the Collectioninto.- Parameters:
into- a Collection of Region that will be modified if this succeedsx- the x-coordinate to look upy- the y-coordinate to look uppacked- the Collection of Region to try to look up the given position in- Returns:
into, potentially modified
-
size
public int size()- Specified by:
sizein interfaceCollection<Coord>
-
fit
-
fit
public int[][] fit(int[][] basis, int defaultValue) -
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 Region, runningseparatedRegionBlue(float)on that surface with the given fractionKept, taking the original Region and removing its whole surface withretract(), then inserting the quasi-randomly-removed surface into this Region 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
-
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 Region, runningseparatedRegionBlue(float)on that surface with the given fractionKept, taking the original Region and removing its whole surface withretract(), then inserting the quasi-randomly-removed surface into this Region to replace its surface with a randomly "damaged" one.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate. After the call, the contents ofbufferwill be the same as a copy of this withretract()called once.- Parameters:
fractionKept- the fraction between 0.0 and 1.0 of how many cells on the outer surface of this to keep "on"buffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- 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, randomly selecting them. This can be thought of as runningsurface()on a copy of this Region, runningdeteriorate(EnhancedRandom, float)on that surface with the given fractionKept, taking the original Region and removing its whole surface withretract(), then inserting the randomly-removed surface into this Region to replace its surface with a randomly "damaged" one.- Parameters:
random- a EnhancedRandom, or a recommended subclass likeWhiskerRandomfractionKept- 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
-
fray
public Region fray(com.github.tommyettinger.random.EnhancedRandom random, float fractionKept, Region buffer) 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, randomly selecting them. This can be thought of as runningsurface()on a copy of this Region, runningdeteriorate(EnhancedRandom, float)on that surface with the given fractionKept, taking the original Region and removing its whole surface withretract(), then inserting the randomly-removed surface into this Region to replace its surface with a randomly "damaged" one.
This overload takes abufferRegion that should be the same size as this one. If it is, this won't allocate. After the call, the contents ofbufferwill be the same as a copy of this withretract()called once.- Parameters:
random- a EnhancedRandom, or a recommended subclass likeWhiskerRandomfractionKept- the fraction between 0.0 and 1.0 of how many cells on the outer surface of this to keep "on"buffer- another Region that will be erased and replaced with the contents of this Region before this call; should be the same size as this- Returns:
- this for chaining
-
randomScatter
public Region randomScatter(com.github.tommyettinger.random.EnhancedRandom rng, int minimumDistance) Modifies this Region 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- a EnhancedRandom, or a recommended subclass likeWhiskerRandomminimumDistance- the minimum distance between "on" cells in the result- Returns:
- this for chaining
-
randomScatter
public Region randomScatter(com.github.tommyettinger.random.EnhancedRandom rng, int minimumDistance, int limit) Modifies this Region 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- a EnhancedRandom, or a recommended subclass likeWhiskerRandomminimumDistance- the minimum distance between "on" cells in the resultlimit- the maximum count of "on" cells to keep- Returns:
- this for chaining
-
rateDensity
public float rateDensity() -
rateRegularity
public float rateRegularity() -
perceptualHashQuick
public void perceptualHashQuick(long[] into, int[] working) Calculates a perceptual hash for this Region using a method that is only precise for some sizes of Region; 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 blockhash by commonsmachinery, 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
public int[] asEncoded() -
asTightEncoded
public int[] asTightEncoded() -
first
Gets the first Coord in the iteration order, or (-1,-1) if this Region is empty.- Returns:
- the first Coord in the iteration order, or (-1,-1) if this Region is empty
-
firstTight
public int firstTight() -
last
Gets the last Coord in the iteration order, or (-1,-1) if this Region is empty.- Returns:
- the last Coord in the iteration order, or (-1,-1) if this Region is empty
-
lastTight
public int lastTight() -
nth
-
atFraction
-
atFractionTight
public int atFractionTight(float fraction) -
singleRandom
Gets a single random Coord from the "on" positions in this Region, or the Coord (-1,-1) if this is empty. Uses the given EnhancedRandom 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 Region 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 callEnhancedRandom.nextInt(int)to get an index inside that Coord array. 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.- Parameters:
rng- a EnhancedRandom, or a recommended subclass likeWhiskerRandom- Returns:
- a single randomly-chosen Coord from the "on" positions in this Region, or (-1,-1) if empty
-
singleRandomTight
public int singleRandomTight(com.github.tommyettinger.random.EnhancedRandom rng) -
interleaveBits
public 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. Essentially, this takes two numbers with bits labeled likea b cfor x andR S Tfor y and makes a number with those bits arranged likeR a S b T c. Numbers made by interleaving other numbers like this are sometimes called Morton codes, and the sequence of Morton codes forms a pattern called the Z-order curve.- 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
public 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). This may be useful for ordering traversals of all points in a Region less predictably. Numbers made by interleaving other numbers, liken, are sometimes called Morton codes, and the sequence of Morton codes forms a pattern called the Z-order curve.- 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;)
-
separatedBlue
Gets a Coord array from the "on" contents of this Region, using a quasi-random scattering of chosen cells with a count that matches the givenfractionof 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.
Internally, this is a thin wrapper aroundseparatedRegionBlue(float, 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 Region, using a quasi-random scattering of chosen cells with a count that matches the givenfractionof 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.
Internally, this is a thin wrapper aroundseparatedRegionBlue(float, 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 Region so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()matches the givenfractionof 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 Region 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
-
separatedRegionBlue
Modifies this Region so it contains a quasi-random subset of its previous contents, choosing cells so that thesize()matches the givenfractionof 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 Region 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 quasi-randomly select, between 0.0 and 1.0limit- the maximum size of the Region to return; a negative number will make this have no limit- Returns:
- this, after modifications, for chaining
-
separatedPoisson
public Coord[] separatedPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance) Gets all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned array. Works on a copy of this Region, so this object won't be modified.- Parameters:
rng- an EnhancedRandom to randomly choose points; may be queried quite a lot for large RegionsminimumDistance- the minimum distance between points to allow; this is a float, and distances will be rounded- Returns:
- a new Coord array containing some of the "on" cells in this Region
-
separatedPoisson
public Coord[] separatedPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance, int limit) Gets all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned array. Works on a copy of this Region, so this object won't be modified. This overload takes a limit; if limit is non-negative, it will be used as the maximum number of "on" cells to permit in the result. When there would otherwise be more "on" cells than the limit, this randomly chooses which ones to keep.- Parameters:
rng- an EnhancedRandom to randomly choose points; may be queried quite a lot for large RegionsminimumDistance- the minimum distance between points to allow; this is a float, and distances will be roundedlimit- the maximum size of the array to return; a negative number will make this have no limit- Returns:
- a new Coord array containing some of the "on" cells in this Region
-
separatedRegionPoisson
public Region separatedRegionPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance) Removes all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned Region. Modifies this Region in-place.- Parameters:
rng- an EnhancedRandom to randomly choose points; may be queried quite a lot for large RegionsminimumDistance- the minimum distance between points to allow; this is a float, and distances will be rounded- Returns:
- this, after modifications, for chaining
-
separatedRegionPoisson
public Region separatedRegionPoisson(com.github.tommyettinger.random.EnhancedRandom rng, float minimumDistance, int limit) Removes all but a quasi-random group of "on" cells that each has at least minimumDistance between itself and any other cell in the returned Region. Modifies this Region in-place. This overload takes a limit; if limit is non-negative, it will be used as the maximum number of "on" cells to permit in the result. When there would otherwise be more "on" cells than the limit, this randomly chooses which ones to keep.- Parameters:
rng- an EnhancedRandom to randomly choose points; may be queried quite a lot for large RegionsminimumDistance- the minimum distance between points to allow; this is a float, and distances will be roundedlimit- the maximum size of the Region to return; a negative number will make this have no limit- Returns:
- this, after modifications, for chaining
-
randomPortion
-
randomRegion
-
contains
public boolean contains(int x, int y) -
isEmpty
public boolean isEmpty()- Specified by:
isEmptyin interfaceCollection<Coord>- Returns:
- Whether this zone is empty.
-
sum
Generates a 2D int array from an array or vararg of Regions, starting at all 0 and adding 1 to the int at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions- an array or vararg of Regions; 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 Regions that had an "on" cell at that position
-
sum
Generates a 2D int array from a List of Regions, starting at all 0 and adding 1 to the int at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions- a List of Regions; 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 Regions that had an "on" cell at that position
-
sumFloat
Generates a 2D float array from an array or vararg of Regions, starting at all 0 and adding 1 to the float at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions- an array or vararg of Regions; must all have the same width and height- Returns:
- a 2D float array with the same width and height as the regions, where an float cell equals the number of given Regions that had an "on" cell at that position
-
sumFloat
Generates a 2D float array from a List of Regions, starting at all 0 and adding 1 to the float at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can produce any number between 0 and 8 in a cell; if you give 16 Regions, then it can produce any number between 0 and 16 in a cell.- Parameters:
regions- a List of Regions; must all have the same width and height- Returns:
- a 2D float array with the same width and height as the regions, where an float cell equals the number of given Regions that had an "on" cell at that position
-
sumWeighted
Generates a 2D int array from an array of Regions and an array of weights, starting the 2D result at all 0 and, for every Region 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 Regions 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 Regions 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 Regions 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 Regions; 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 Regions that had an "on" cell at that position
-
sumWeightedFloat
Generates a 2D float array from an array of Regions and an array of weights, starting the 2D result at all 0 and, for every Region that has that cell as "on," adding the float in the corresponding weights array at the position of that cell. This means if you give an array of 4 Regions 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 Regions 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 Regions 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 Regions; must all have the same width and heightweights- an array of floats; must have length at least equal to regions' length- Returns:
- a 2D float array with the same width and height as the regions, where an float cell equals the sum of the weights corresponding to Regions that had an "on" cell at that position
-
sumInto
Adds to an existing 2D int array with an array or vararg of Regions, adding 1 to the int in existing at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 Regions, 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 Regionsregions- an array or vararg of Regions; must all have the same width and height- Returns:
- existing, after modification, where an int cell will be changed by the number of given Regions that had an "on" cell at that position
-
sumIntoFloat
Adds to an existing 2D float array with an array or vararg of Regions, adding 1 to the float in existing at a position once for every Region that has that cell as "on." This means if you give 8 Regions to this method, it can increment by any number between 0 and 8 in a cell; if you give 16 Regions, then it can increase the value in existing by any number between 0 and 16 in a cell.- Parameters:
existing- a non-null 2D float array that will have each cell incremented by the sum of the Regionsregions- an array or vararg of Regions; must all have the same width and height- Returns:
- existing, after modification, where a float cell will be changed by the number of given Regions that had an "on" cell at that position
-
bitSum
Generates a 2D int array from an array or vararg of Regions, 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 Regions to this method, it can produce any 8-bit number in a cell (0-255); if you give 16 Regions, then it can produce any 16-bit number (0-65535).- Parameters:
regions- an array or vararg of Regions; 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
-
dijkstraScan
A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available. Starting atgoal, this floods outward (4-way) as withflood(Region), modifyingintoso each cell reached during the course of repeated flooding has an int value equal to the (Manhattan) distance fromgoalto that cell, and all other cells will be set toInteger.MAX_VALUE. This will callflood(Region)until it can't reach any more cells. This returnsinto, after modifications.- Parameters:
into- a 2D int array that will have all reachable cells assigned their distance from goal, and all others toInteger.MAX_VALUEgoal- the starting point for the scan/flood-fill;intowill be assigned 0 at this point- Returns:
into, after modifications
-
dijkstraScan
A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available. Starting atgoal, this floods outward (4-way) as withflood(Region), modifyingintoso each cell reached during the course of repeated flooding has an int value equal to the (Manhattan) distance fromgoalto that cell, and all other cells will be set toInteger.MAX_VALUE. Thelimitis the exclusive upper bound for the greatest distance from thegoalthis will change; this will callflood(Region)at mostlimittimes, and can call it fewer times if it tries to flood but can't reach any more cells. This returnsinto, after modifications.- Parameters:
into- a 2D int array that will have all reachable cells assigned their distance from goal, and all others toInteger.MAX_VALUEgoal- the starting point for the scan/flood-fill;intowill be assigned 0 at this pointlimit- the exclusive upper bound on the distance this can travel from thegoal- Returns:
into, after modifications
-
dijkstraScan
A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available. Starting at each "on" cell ingoals, this floods outward (4-way) as withflood(Region), modifyingintoso each cell reached during the course of repeated flooding has an int value equal to the (Manhattan) distance fromgoalto that cell, and all other cells will be set toInteger.MAX_VALUE. This will callflood(Region)until it can't reach any more cells. Note, this modifies bothintoandgoals, but usually the result ingoalsisn't very useful (you may want to get itssize()to know how many cells were affected, but it can't tell you the distance for any particular cell). This returnsinto, after modifications.- Parameters:
into- a 2D int array that will have all reachable cells assigned their distance from goal, and all others toInteger.MAX_VALUEgoals- the starting points for the scan/flood-fill; will be modified by repeatedly calling flood()- Returns:
into, after modifications
-
dijkstraScan
A crude approximation of DijkstraMap's scan() method for when DijkstraMap isn't available. Starting at each "on" cell ingoals, this floods outward (4-way) as withflood(Region), modifyingintoso each cell reached during the course of repeated flooding has an int value equal to the (Manhattan) distance fromgoalto that cell, and all other cells will be set toInteger.MAX_VALUE. Thelimitis the exclusive upper bound for the greatest distance from a goal this will change; this will callflood(Region)at mostlimittimes, and can call it fewer times if it tries to flood but can't reach any more cells. Note, this modifies bothintoandgoals, but usually the result ingoalsisn't very useful (you may want to get itssize()to know how many cells were affected, but it can't tell you the distance for any particular cell). This returnsinto, after modifications.- Parameters:
into- a 2D int array that will have all reachable cells assigned their distance from goal, and all others toInteger.MAX_VALUEgoals- the starting points for the scan/flood-fill; will be modified by repeatedly calling flood()limit- the exclusive upper bound on the distance this can travel from thegoal- Returns:
into, after modifications
-
equals
-
hashCode
public int hashCode()- Specified by:
hashCodein interfaceCollection<Coord>- Overrides:
hashCodein classObject
-
hash64
public long hash64() -
hash64
public long hash64(long seed) Computes a 64-bit hash code of this Region given a 64-bit seed; even if given two very similar seeds, this should produce very different hash codes for the same Region.
Meant for potential use in Bloom filters. UsesHasher'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 Region
-
stringSerialize
-
stringDeserialize
-
of
Constructs a Region using a vararg for data. Primarily meant for generated code, sincestringSerialize()produces a String that happens to be a valid parameter list for this method.- Parameters:
width- width of the Region to produceheight- height of the Region to producedata- array or vararg of long containing the exact data, probably from an existing Region- Returns:
- a new Region with the given width, height, and data
-
toCompressedString
Compresses this Region into a UTF-16 String and returns the String without modifying this Region. UsesHilbertCurve's algorithm and data to compress this Region in 256x128 blocks, storing the HilbertCurve 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 Region using
decompress(String)
-
decompress
Decompresses a String returned bytoCompressedString(), returning a new Region with identical width, height, and contents to the Region before compression. This decompresses theLZSEncodingapplied to the data, then decompresses theHilbertCurveRLE data to get the original Region back.- Parameters:
compressed- a String that was compressed bytoCompressedString(), without changes- Returns:
- a new copy of the Region that was previously compressed
-
decompressInto
Decompresses a String returned bytoCompressedString(), and assigns into this region the width, height, and contents of the data before compression. This decompresses theLZSEncodingapplied to the data, then decompresses theHilbertCurveRLE data to get the original Region's size and contents back.- Parameters:
compressed- a String that was compressed bytoCompressedString(), without changes- Returns:
- this, for chaining
-
contains
- Specified by:
containsin interfaceCollection<Coord>
-
iterator
-
toArray
- Specified by:
toArrayin interfaceCollection<Coord>
-
toArray
public <T> T[] toArray(T[] a) - Specified by:
toArrayin interfaceCollection<Coord>
-
add
- Specified by:
addin interfaceCollection<Coord>
-
clear
public void clear()- Specified by:
clearin interfaceCollection<Coord>
-
remove
- Specified by:
removein interfaceCollection<Coord>
-
containsAll
- Specified by:
containsAllin interfaceCollection<Coord>
-
addAll
- Specified by:
addAllin interfaceCollection<Coord>
-
removeAll
- Specified by:
removeAllin interfaceCollection<Coord>
-
retainAll
- Specified by:
retainAllin interfaceCollection<Coord>
-
deteriorate
Randomly removes points from a Region, 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 Region
-
deteriorate
public Region deteriorate(com.github.tommyettinger.random.EnhancedRandom random, float preservation) Randomly removes points from a Region, 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 Region), while anything less than 0.015625 (1.0/64) will empty this Region (usingempty()) and then return it. The parameterrandomcan be a plainEnhancedRandom, but will be much faster and have less potential for patterns or artifacts in the output if you useWhiskerRandomor another higher-quality subclass.- Parameters:
random- a EnhancedRandom or a recommended subclass, likeWhiskerRandompreservation- the rough fraction of points to keep, between 0.0 and 1.0- Returns:
- a randomly modified change to this Region
-
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 Region that has been mirrored along the rightmost edge, parallel to the y-axis. The new Region 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 Regions will be the same, that is, any area not added to the original will be equal to the original.- Returns:
- a new Region with twice the width of
this, that is mirrored along the rightmost edge
-
contains
Checks ifcis present in this Region. Returns true if and only if c is present in this Region 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.- Parameters:
c- a Coord to try to find in this Region; if null this will always return false- Returns:
- true if
cis an "on" cell in this Region, or false otherwise, including if c is null
-
xBound
public int xBound(boolean findSmallest) - Parameters:
findSmallest- if true, finds the smallest x-coordinate value; if false, finds the biggest.- Returns:
- The x-coordinate of the Coord within
thisthat has the smallest (or biggest) x-coordinate. Or -1 if the zone is empty.
-
yBound
public int yBound(boolean findSmallest) - Parameters:
findSmallest- if true, finds the smallest y-coordinate value; if false, finds the biggest.- Returns:
- The y-coordinate of the Coord within
thisthat has the smallest (or biggest) y-coordinate. Or -1 if the zone is empty.
-