Interface Grid2D
- All Superinterfaces:
Serializable
- All Known Implementing Classes:
AbstractGrid2D
,DenseGrid2D
,DoubleGrid2D
,IntGrid2D
,ObjectGrid2D
,SparseGrid2D
Toroidal Computation
If you're using the Grid to define a toroidal (wrap-around) world, you can use the tx and ty methods to simplify the math for you. For example, to increment in the x direction, including wrap-around, you can do: x = tx(x+1).
If you're sure that the values you'd pass into the toroidal functions would not wander off more than a grid dimension in either direction (height, width), you can use the slightly faster toroidal functions stx and sty instead. For example, to increment in the x direction, including wrap-around, you can do: x = stx(x+1). See the documentation on these functions for when they're appropriate to use. Under most common situations, they're okay.
In HotSpot 1.4.1, stx, and sty are inlined. In Hotspot 1.3.1, they are not (they contain if-statements).
Hex Grid Computation
Grids can be used for both squares and hex grids. Hex grids are stored in an ordinary rectangular array and are defined as follows:(0,0) (2,0) (4,0) (6,0) ... (1,0) (3,0) (5,0) (7,0) ... (0,1) (2,1) (4,1) (6,1) ... (1,1) (3,1) (5,1) (7,1) ... (0,2) (2,2) (4,2) (6,2) ... (1,2) (3,2) (5,2) (7,2) ... ... ... ... ... ... ... ... ... ... ...
The rules moving from a hex location (at CENTER) to another one are as follows:
UP x UPLEFT y - 1 UPRIGHT x - 1 x + 1 ((x % 2) == 0) ? y - 1 : y CENTER ((x % 2) == 0) ? y - 1 : y x DOWNLEFT y DOWNRIGHT x - 1 x + 1 ((x % 2) == 0) ? y : y + 1 DOWN ((x % 2) == 0) ? y : y + 1 x y + 1NOTE: (x % 2 == 0), that is, "x is even", may be written instead in this faster way: ((x invalid input: '&' 1) == 0)
Because the math is a little hairy, we've provided the math for the UPLEFT, UPRIGHT, DOWNLEFT, and DOWNRIGHT directions for you. For example, the UPLEFT location from [x,y] is at [ulx(x,y) , uly(x,y)]. Additionally, the toroidal methods can be used in conjunction with the hex methods to implement a toroidal hex grid. Be sure to To use a toroidal hex grid properly, you must ensure that height of the grid is an even number. For example, the toroidal UPLEFT X location is at tx(ulx(x,y)) and the UPLEFT Y location is at ty(uly(x,y)). Similarly, you can use stx and sty.
While this interface defines various methods common to many grids, you should endeavor not to call these grids casted into this interface: it's slow. If you call the grids' methods directly by their class, their methods are almost certain to be inlined into your code, which is very fast.
Triangular Grid Computation
Grids can also be used for triangular grids instead of squares. Triangular grids look like this:------------------------- \(0,0)/ \(2,0)/ \(4,0)/ \ \ / \ / \ / \ ... \ /(1,0)\ /(3,0)\ /(5,0)\ ------------------------- / \(1,1)/ \(3,1)/ \(5,1)/ / \ / \ / \ / ... /(0,1)\ /(2,1)\ /(4,1)\ / ------------------------- \(0,2)/ \(2,2)/ \(4,2)/ \ \ / \ / \ / \ ... \ /(1,2)\ /(3,2)\ /(5,2)\ ------------------------- / \(1,3)/ \(3,3)/ \(5,3)/ / \ / \ / \ / ... /(0,3)\ /(2,3)\ /(4,3)\ / ------------------------- . . .
How do you get around such a beast? Piece of cake! Well, to go to your right or left neighbor, you just add or subtract the X value. To go to your up or down neighbor, all you do is add or subtract the Y value. All you need to know is if your triangle has an edge on the top (so you can go up) or an edge on the bottom (so you can go down). The functions TRB (triangle with horizontal edge on 'bottom') and TRT (triangle with horizontal edge on 'top') will tell you this.
Like the others, the triangular grid can also be used in toroidal fashion, and the toroidal functions should work properly with it. To use a toroidal triangular grid, you should ensure that your grid's length and width are both even numbers.
We'll provide a distance-measure function for triangular grids just as soon as we figure out what the heck one looks like. :-)
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
"All" measurement rule for raidal neighborhood lookup.static final int
"Any" measurement rule for raidal neighborhood lookup.static final int
Pass this into buildMap to indicate that it should make a map of any size it likes.static final int
Bounded Mode for neighborhood lookup.static final int
Center measurement rule for raidal neighborhood lookup.static final int
Bounded Mode for toroidal lookup.static final int
Bounded Mode for neighborhood lookup. -
Method Summary
Modifier and TypeMethodDescriptionbuildMap
(int size) Creates a map of the provided size (or any size it likes if ANY_SIZE is passed in).Creates a Map which is a copy of another.int
dlx
(int x, int y) Hex downleft x.int
dly
(int x, int y) Hex downleft y.int
downx
(int x, int y) Hex down x.int
downy
(int x, int y) Hex down y.int
drx
(int x, int y) Hex downright x.int
dry
(int x, int y) Hex downright y.int
Returns the width of the field.void
getHexagonalLocations
(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors located within the hexagon centered at (X,Y) and 2*dist+1 cells from point to opposite point inclusive.void
getMooreLocations
(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors of a location that satisfy max( abs(x-X) , abs(y-Y) ) invalid input: '<'= dist.void
getNeighborsHamiltonianDistance
(int x, int y, int dist, boolean toroidal, IntBag xPos, IntBag yPos) Deprecated.void
getNeighborsHexagonalDistance
(int x, int y, int dist, boolean toroidal, IntBag xPos, IntBag yPos) Deprecated.void
getNeighborsMaxDistance
(int x, int y, int dist, boolean toroidal, IntBag xPos, IntBag yPos) Deprecated.void
getRadialLocations
(int x, int y, double dist, int mode, boolean includeOrigin, int measurementRule, boolean closed, IntBag xPos, IntBag yPos) Gets all neighbors overlapping with a circular region centered at (X,Y) and with a radius of dist.void
getRadialLocations
(int x, int y, double dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors overlapping with a circular region centered at (X,Y) and with a radius of dist.void
getVonNeumannLocations
(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors of a location that satisfy abs(x-X) + abs(y-Y) invalid input: '<'= dist.int
getWidth()
Returns the width of the field.void
reshape
(int width, int height) Entirely wipes the grid and reshapes it into a different sized rectangle.int
stx
(int x) Simple [and fast] toroidal x.int
sty
(int y) Simple [and fast] toroidal y.boolean
trb
(int x, int y) Horizontal edge is on the bottom for triangle.boolean
trt
(int x, int y) Horizontal edge is on the top for triangle.int
tx
(int x) Toroidal x.int
ty
(int y) Toroidal y.int
ulx
(int x, int y) Hex upleft x.int
uly
(int x, int y) Hex upleft y.int
upx
(int x, int y) Hex up x.int
upy
(int x, int y) Hex up y.int
urx
(int x, int y) Hex upright x.int
ury
(int x, int y) Hex upright y.
-
Field Details
-
BOUNDED
static final int BOUNDEDBounded Mode for neighborhood lookup. Indicates that the Grid2D in question is being used in a way that assumes that it has no valid locations outside of the rectangle starting at (0,0) and ending at (width-1, height-1) inclusive.- See Also:
-
UNBOUNDED
static final int UNBOUNDEDBounded Mode for neighborhood lookup. Indicates that the Grid2D in question is being used in a way that assumes that any numerical location is a valid location. Note that Grid2D subclasses based on arrays, such as DoubleGrid2D, IntGrid2D, ObjectGrid2D, and DenseGrid2D, cannot be used in an unbounded fashion.- See Also:
-
TOROIDAL
static final int TOROIDALBounded Mode for toroidal lookup. Indicates that the Grid2D in question is being used in a way that assumes that it is bounded, but wrap-around: for example, (0,0) is located one away diagonally from (width-1, height-1).- See Also:
-
CENTER
static final int CENTERCenter measurement rule for raidal neighborhood lookup. Indicates that radial lookup will include locations whose grid cell centers overlap with the neighborhood region.- See Also:
-
ALL
static final int ALL"All" measurement rule for raidal neighborhood lookup. Indicates that radial lookup will include locations whose grid cells are entirely within the neighborhood region.- See Also:
-
ANY
static final int ANY"Any" measurement rule for raidal neighborhood lookup. Indicates that radial lookup will include locations whose grid cells have any overlap at all with the neighborhood region.- See Also:
-
ANY_SIZE
static final int ANY_SIZEPass this into buildMap to indicate that it should make a map of any size it likes.- See Also:
-
-
Method Details
-
getWidth
int getWidth()Returns the width of the field. -
getHeight
int getHeight()Returns the width of the field. -
reshape
void reshape(int width, int height) Entirely wipes the grid and reshapes it into a different sized rectangle. You should generally not call this: it's used for exotic purposes such as in Distributed MASON. -
tx
int tx(int x) Toroidal x. The following definition:
final int length = this.length;
if (z >= 0) return (z % length);
final int length2 = (z % length) + length;
if (length2 < length) return length2;
return 0;
... produces the correct code and is 27 bytes, so it's likely to be inlined in Hotspot for 1.4.1. -
ty
int ty(int y) Toroidal y. The following definition:
final int length = this.length;
if (z >= 0) return (z % length);
final int length2 = (z % length) + length;
if (length2 invalid input: '<' length) return length2;
return 0;
... produces the correct code and is 27 bytes, so it's likely to be inlined in Hotspot for 1.4.1. -
stx
int stx(int x) Simple [and fast] toroidal x. Use this if the values you'd pass in never stray beyond (-width ... width * 2) not inclusive. It's a bit faster than the full toroidal computation as it uses if statements rather than two modulos. The following definition:
{ int width = this.width; if (x >= 0) { if (x invalid input: '<' width) return x; return x - width; } return x + width; } ...produces the shortest code (24 bytes) and is inlined in Hotspot for 1.4.1. However in most cases removing the int width = this.width; is likely to be a little faster if most objects are usually within the toroidal region. -
sty
int sty(int y) Simple [and fast] toroidal y. Use this if the values you'd pass in never stray beyond (-height ... height * 2) not inclusive. It's a bit faster than the full toroidal computation as it uses if statements rather than two modulos. The following definition:
{ int height = this.height; if (y >= 0) { if (y invalid input: '<' height) return y ; return y - height; } return y + height; } ...produces the shortest code (24 bytes) and is inlined in Hotspot for 1.4.1. However in most cases removing the int height = this.height; is likely to be a little faster if most objects are usually within the toroidal region. -
ulx
int ulx(int x, int y) Hex upleft x. -
uly
int uly(int x, int y) Hex upleft y. -
urx
int urx(int x, int y) Hex upright x. -
ury
int ury(int x, int y) Hex upright y. -
dlx
int dlx(int x, int y) Hex downleft x. -
dly
int dly(int x, int y) Hex downleft y. -
drx
int drx(int x, int y) Hex downright x. -
dry
int dry(int x, int y) Hex downright y. -
upx
int upx(int x, int y) Hex up x. -
upy
int upy(int x, int y) Hex up y. -
downx
int downx(int x, int y) Hex down x. -
downy
int downy(int x, int y) Hex down y. -
trb
boolean trb(int x, int y) Horizontal edge is on the bottom for triangle. True if x + y is odd. One definition of this is return ((x + y) invalid input: '&' 1) == 1; -
trt
boolean trt(int x, int y) Horizontal edge is on the top for triangle. True if x + y is even. One definition of this is return ((x + y) invalid input: '&' 1) == 0; -
getNeighborsMaxDistance
Deprecated.Gets all neighbors of a location that satisfy max( abs(x-X) , abs(y-Y) ) invalid input: '<'= dist. This region forms a square 2*dist+1 cells across, centered at (X,Y). If dist==1, this is equivalent to the so-called "Moore Neighborhood" (the eight neighbors surrounding (X,Y)), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may only run in two modes: toroidal or bounded. Unbounded lookup is not permitted, and so this function is deprecated: instead you should use the other version of this function which has more functionality. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
The origin -- that is, the (x,y) point at the center of the neighborhood -- is always included in the results.
This function is equivalent to: getNeighborsMaxDistance(x,y,dist,toroidal ? Grid2D.TOROIDAL : Grid2D.BOUNDED, true, xPos, yPos);
-
getMooreLocations
void getMooreLocations(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors of a location that satisfy max( abs(x-X) , abs(y-Y) ) invalid input: '<'= dist. This region forms a square 2*dist+1 cells across, centered at (X,Y). If dist==1, this is equivalent to the so-called "Moore Neighborhood" (the eight neighbors surrounding (X,Y)), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may be run in one of three modes: Grid2D.BOUNDED, Grid2D.UNBOUNDED, and Grid2D.TOROIDAL. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. If "unbounded", then the neighbors are not so restricted. Note that unbounded neighborhood lookup only makes sense if your grid allows locations to actually be outside this box. For example, SparseGrid2D permits this but ObjectGrid2D and DoubleGrid2D and IntGrid2D and DenseGrid2D do not. Finally if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
You can also opt to include the origin -- that is, the (x,y) point at the center of the neighborhood -- in the neighborhood results.
-
getNeighborsHamiltonianDistance
void getNeighborsHamiltonianDistance(int x, int y, int dist, boolean toroidal, IntBag xPos, IntBag yPos) Deprecated.Gets all neighbors of a location that satisfy abs(x-X) + abs(y-Y) invalid input: '<'= dist. This region forms a diamond 2*dist+1 cells from point to opposite point inclusive, centered at (X,Y). If dist==1 this is equivalent to the so-called "Von-Neumann Neighborhood" (the four neighbors above, below, left, and right of (X,Y)), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may only run in two modes: toroidal or bounded. Unbounded lookup is not permitted, and so this function is deprecated: instead you should use the other version of this function which has more functionality. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
The origin -- that is, the (x,y) point at the center of the neighborhood -- is always included in the results.
This function is equivalent to: getNeighborsHamiltonianDistance(x,y,dist,toroidal ? Grid2D.TOROIDAL : Grid2D.BOUNDED, true, xPos, yPos);
-
getVonNeumannLocations
void getVonNeumannLocations(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors of a location that satisfy abs(x-X) + abs(y-Y) invalid input: '<'= dist. This region forms a diamond 2*dist+1 cells from point to opposite point inclusive, centered at (X,Y). If dist==1 this is equivalent to the so-called "Von-Neumann Neighborhood" (the four neighbors above, below, left, and right of (X,Y)), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may be run in one of three modes: Grid2D.BOUNDED, Grid2D.UNBOUNDED, and Grid2D.TOROIDAL. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. If "unbounded", then the neighbors are not so restricted. Note that unbounded neighborhood lookup only makes sense if your grid allows locations to actually be outside this box. For example, SparseGrid2D permits this but ObjectGrid2D and DoubleGrid2D and IntGrid2D and DenseGrid2D do not. Finally if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
You can also opt to include the origin -- that is, the (x,y) point at the center of the neighborhood -- in the neighborhood results.
-
getNeighborsHexagonalDistance
void getNeighborsHexagonalDistance(int x, int y, int dist, boolean toroidal, IntBag xPos, IntBag yPos) Deprecated.Gets all neighbors located within the hexagon centered at (X,Y) and 2*dist+1 cells from point to opposite point inclusive. If dist==1, this is equivalent to the six neighbors immediately surrounding (X,Y), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may only run in two modes: toroidal or bounded. Unbounded lookup is not permitted, and so this function is deprecated: instead you should use the other version of this function which has more functionality. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
The origin -- that is, the (x,y) point at the center of the neighborhood -- is always included in the results.
This function is equivalent to: getNeighborsHexagonalDistance(x,y,dist,toroidal ? Grid2D.TOROIDAL : Grid2D.BOUNDED, true, xPos, yPos);
-
getHexagonalLocations
void getHexagonalLocations(int x, int y, int dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors located within the hexagon centered at (X,Y) and 2*dist+1 cells from point to opposite point inclusive. If dist==1, this is equivalent to the six neighbors immediately surrounding (X,Y), plus (X,Y) itself. Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.This function may be run in one of three modes: Grid2D.BOUNDED, Grid2D.UNBOUNDED, and Grid2D.TOROIDAL. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. If "unbounded", then the neighbors are not so restricted. Note that unbounded neighborhood lookup only makes sense if your grid allows locations to actually be outside this box. For example, SparseGrid2D permits this but ObjectGrid2D and DoubleGrid2D and IntGrid2D and DenseGrid2D do not. Finally if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
You can also opt to include the origin -- that is, the (x,y) point at the center of the neighborhood -- in the neighborhood results.
-
getRadialLocations
void getRadialLocations(int x, int y, double dist, int mode, boolean includeOrigin, IntBag xPos, IntBag yPos) Gets all neighbors overlapping with a circular region centered at (X,Y) and with a radius of dist. The measurement rule is Grid2D.ANY, meaning those cells which overlap at all with the region. The region is closed, meaning that that points which touch on the outer surface of the circle will be considered members of the region.Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.
This function may be run in one of three modes: Grid2D.BOUNDED, Grid2D.UNBOUNDED, and Grid2D.TOROIDAL. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. If "unbounded", then the neighbors are not so restricted. Note that unbounded neighborhood lookup only makes sense if your grid allows locations to actually be outside this box. For example, SparseGrid2D permits this but ObjectGrid2D and DoubleGrid2D and IntGrid2D and DenseGrid2D do not. Finally if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
You can also opt to include the origin -- that is, the (x,y) point at the center of the neighborhood -- in the neighborhood results.
-
getRadialLocations
void getRadialLocations(int x, int y, double dist, int mode, boolean includeOrigin, int measurementRule, boolean closed, IntBag xPos, IntBag yPos) Gets all neighbors overlapping with a circular region centered at (X,Y) and with a radius of dist. If measurementRule is Grid2D.CENTER, then the measurement rule will be those cells whose centers overlap with the region. If measurementRule is Grid2D.ALL, then the measurement rule will be those cells which entirely overlap with the region. If measurementrule is Grid2D.ANY, then the measurement rule will be those cells which overlap at all with the region. If closed is true, then the region will be considered "closed", that is, that points which touch on the outer surface of the circle will be considered members of the region. If closed is open, then the region will be considered "open", that is, that points which touch on the outer surface of the circle will NOT be considered members of the region.Places each x and y value of these locations in the provided IntBags xPos and yPos, clearing the bags first.
This function may be run in one of three modes: Grid2D.BOUNDED, Grid2D.UNBOUNDED, and Grid2D.TOROIDAL. If "bounded", then the neighbors are restricted to be only those which lie within the box ranging from (0,0) to (width, height), that is, the width and height of the grid. If "unbounded", then the neighbors are not so restricted. Note that unbounded neighborhood lookup only makes sense if your grid allows locations to actually be outside this box. For example, SparseGrid2D permits this but ObjectGrid2D and DoubleGrid2D and IntGrid2D and DenseGrid2D do not. Finally if "toroidal", then the environment is assumed to be toroidal, that is, wrap-around, and neighbors are computed in this fashion. Toroidal locations will not appear multiple times: specifically, if the neighborhood distance is so large that it wraps completely around the width or height of the box, neighbors will not be counted multiple times. Note that to ensure this, subclasses may need to resort to expensive duplicate removal, so it's not suggested you use so unreasonably large distances.
You can also opt to include the origin -- that is, the (x,y) point at the center of the neighborhood -- in the neighborhood results.
-
buildMap
Creates a Map which is a copy of another. By default, HashMap is used. -
buildMap
Creates a map of the provided size (or any size it likes if ANY_SIZE is passed in). By default, HashMap is used.
-