Class HilbertCurve
java.lang.Object
com.github.yellowstonegames.grid.HilbertCurve
Calculates and stores 2D and optionally 3D Hilbert Curves up to a reasonable size.
This can be used for various purposes, from creating a path in dungeon generation to
optimizing certain kinds of compression that benefit from the qualities of a Hilbert
Curve. A Hilbert Curve is, at its simplest, a way of passing through each point on a
(typically square) grid without ever crossing its own path or taking a diagonal step.
Hilbert Curves are self-similar, like many fractals; if you cut out a quarter of any
large Hilbert Curve, the part cut out will be shaped similarly to the original Curve.
The biggest area where Hilbert Curves find application is in applications that demand
nearby locations in 2D or 3D space to have nearby numerical values (here, the
distance traveled along the Hilbert Curve to get to that location) as often as
possible. A Hilbert Curve is a path, so a distance down that path is a single number,
but because it touches all grid points, that one number can be used to identify any
grid point in 2D, 3D, or higher-dimensional space. Unlike some other "space-filling
curves," like the more-common and easier-to-calculate Z-order curve, the Hilbert
Curve doesn't move diagonally or jump long distances between sequential points, so it
very often tends to have very close distances for very nearby 2D points.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intstatic char[]static char[]static char[]static char[]static char[]static char[]static char[]static char[]static char[]static char[] -
Method Summary
Modifier and TypeMethodDescriptionstatic intcoordToHilbert(Coord pt) Takes a position as a Coord called pt and returns the length to travel along the 256x256 Hilbert curve to reach that position.static intcoordToMoore(Coord pt) Takes a position as a Coord called pt and returns the length to travel along the 16x16 Moore curve to reach that position.static intgetXMoore3D(int index, int n) Gets the x coordinate for a given index into the 16x16x(8*n) Moore curve.static intgetYMoore3D(int index, int n) Gets the y coordinate for a given index into the 16x16x(8*n) Moore curve.static intgetZMoore3D(int index, int n) Gets the z coordinate for a given index into the 16x16x(8*n) Moore curve.static intgrayDecode(int n) Decode a number from a Gray code n; Gray codes have a relation to the Hilbert curve and may be useful.static intgrayEncode(int n) Encode a number n as a Gray code; Gray codes have a relation to the Hilbert curve and may be useful.static CoordhilbertToCoord(int hilbert) Takes a distance to travel along the 256x256 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve.static inthilbertToMorton(int hilbert) Takes a distance to travel along the 256x256 Hilbert curve and returns a Morton code representing the position in 2D space that corresponds to that point on the Hilbert Curve; the Morton code will have interleaved x and y bits and x in the least significant bit.static voidinit2D()static voidinit3D()static CoordmooreToCoord(int moore) Takes a distance to travel along the 16x16 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve.static intmortonBitDecode3D(int morton) Given a 15-bit Morton code (typically produced bymortonEncode3D(int, int, int)), this unpacks the three interleaved numbers into contiguous 5-bit sections of the returned int.static CoordmortonDecode(int morton) Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position.static intmortonEncode(int index1, int index2) Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit.static intmortonEncode3D(int index1, int index2, int index3) Given three 5-bit index parameters, encodes them all into a 15-bit Morton code.static intmortonToHilbert(int morton) Takes a position as a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the length to travel along the 256x256 Hilbert Curve to reach that position.static intposToHilbert(int x, int y) Takes an x, y position and returns the length to travel along the 256x256 Hilbert curve to reach that position.static intposToHilbert3D(int x, int y, int z) Takes an x, y, z position and returns the length to travel along the 8x8x8 Hilbert curve to reach that position.static intposToMoore(int x, int y) Takes an x, y position and returns the length to travel along the 16x16 Moore curve to reach that position.
-
Field Details
-
DEPTH
public static final int DEPTH- See Also:
-
hilbertX
public static char[] hilbertX -
hilbertY
public static char[] hilbertY -
hilbertDistances
public static char[] hilbertDistances -
mooreX
public static char[] mooreX -
mooreY
public static char[] mooreY -
mooreDistances
public static char[] mooreDistances -
hilbert3X
public static char[] hilbert3X -
hilbert3Y
public static char[] hilbert3Y -
hilbert3Z
public static char[] hilbert3Z -
hilbert3Distances
public static char[] hilbert3Distances
-
-
Method Details
-
init2D
public static void init2D() -
init3D
public static void init3D() -
grayEncode
public static int grayEncode(int n) Encode a number n as a Gray code; Gray codes have a relation to the Hilbert curve and may be useful. Source: 2π.com (page no longer exists), The Aggregate Magic Algorithms- Parameters:
n- any int- Returns:
- the gray code for n
-
grayDecode
public static int grayDecode(int n) Decode a number from a Gray code n; Gray codes have a relation to the Hilbert curve and may be useful. Source: 2π.com (page no longer exists), The Aggregate Magic Algorithms- Parameters:
n- a gray code, as produced by grayEncode- Returns:
- the decoded int
-
posToHilbert
public static int posToHilbert(int x, int y) Takes an x, y position and returns the length to travel along the 256x256 Hilbert curve to reach that position. This assumes x and y are between 0 and 255, inclusive. This uses a lookup table for the 256x256 Hilbert Curve, which should make it faster than calculating the distance along the Hilbert Curve repeatedly. Source: and-what-happened blog post.- Parameters:
x- between 0 and 255 inclusivey- between 0 and 255 inclusive- Returns:
- the distance to travel along the 256x256 Hilbert Curve to get to the given x, y point.
-
posToHilbert3D
public static int posToHilbert3D(int x, int y, int z) Takes an x, y, z position and returns the length to travel along the 8x8x8 Hilbert curve to reach that position. This assumes x, y, and z are between 0 and 7, inclusive. This uses a lookup table for the 8x8x8 Hilbert Curve, which should make it faster than calculating the distance along the Hilbert Curve repeatedly. Source: and-what-happened blog post.- Parameters:
x- between 0 and 7 inclusivey- between 0 and 7 inclusivez- between 0 and 7 inclusive- Returns:
- the distance to travel along the 8x8x8 Hilbert Curve to get to the given x, y, z point.
-
posToMoore
public static int posToMoore(int x, int y) Takes an x, y position and returns the length to travel along the 16x16 Moore curve to reach that position. This assumes x and y are between 0 and 15, inclusive. This uses a lookup table for the 16x16 Moore Curve, which should make it faster than calculating the distance along the Moore Curve repeatedly.- Parameters:
x- between 0 and 15 inclusivey- between 0 and 15 inclusive- Returns:
- the distance to travel along the 16x16 Moore Curve to get to the given x, y point.
-
mortonToHilbert
public static int mortonToHilbert(int morton) Takes a position as a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the length to travel along the 256x256 Hilbert Curve to reach that position. This uses 16 bits of the Morton code and requires that the code is non-negative. Source: and-what-happened blog post.- Parameters:
morton- a Morton code that interleaves two 8-bit unsigned numbers, with x as index1 and y as index2.- Returns:
- a distance to travel down the Hilbert Curve to reach the location that can be decoded from morton.
-
hilbertToMorton
public static int hilbertToMorton(int hilbert) Takes a distance to travel along the 256x256 Hilbert curve and returns a Morton code representing the position in 2D space that corresponds to that point on the Hilbert Curve; the Morton code will have interleaved x and y bits and x in the least significant bit. This uses a lookup table for the 256x256 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter hilbert is an int but only 16 unsigned bits are used.- Parameters:
hilbert- a distance to travel down the Hilbert Curve- Returns:
- a Morton code that stores x and y interleaved; can be converted to a Coord with other methods.
-
hilbertToCoord
Takes a distance to travel along the 256x256 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve. This uses a lookup table for the 256x256 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter hilbert is an int but only 16 unsigned bits are used.- Parameters:
hilbert- a distance to travel down the Hilbert Curve- Returns:
- a Coord corresponding to the position in 2D space at the given distance down the Hilbert Curve
-
mooreToCoord
Takes a distance to travel along the 16x16 Hilbert curve and returns a Coord representing the position in 2D space that corresponds to that point on the Hilbert curve. This uses a lookup table for the 16x16 Hilbert curve, which should make it faster than calculating the position repeatedly. The parameter moore is an int but only 8 unsigned bits are used, and since the Moore Curve loops, it is calculated asmoore & 255.- Parameters:
moore- a distance to travel down the Moore Curve- Returns:
- a Coord corresponding to the position in 2D space at the given distance down the Hilbert Curve
-
coordToHilbert
Takes a position as a Coord called pt and returns the length to travel along the 256x256 Hilbert curve to reach that position. This assumes pt.x and pt.y are between 0 and 255, inclusive. Source: and-what-happened blog post.- Parameters:
pt- a Coord with values between 0 and 255, inclusive- Returns:
- a distance from the start of the 256x256 Hilbert curve to get to the position of pt
-
coordToMoore
Takes a position as a Coord called pt and returns the length to travel along the 16x16 Moore curve to reach that position. This assumes pt.x and pt.y are between 0 and 15, inclusive.- Parameters:
pt- a Coord with values between 0 and 15, inclusive- Returns:
- a distance from the "start" of the 16x16 Moore curve to get to the position of pt
-
mortonEncode3D
public static int mortonEncode3D(int index1, int index2, int index3) Given three 5-bit index parameters, encodes them all into a 15-bit Morton code. Source: and-what-happened blog post.- Parameters:
index1- an int between 0 and 31, both inclusiveindex2- an int between 0 and 31, both inclusiveindex3- an int between 0 and 31, both inclusive- Returns:
- a 15-bit int encoding all three index parameters
-
mortonBitDecode3D
public static int mortonBitDecode3D(int morton) Given a 15-bit Morton code (typically produced bymortonEncode3D(int, int, int)), this unpacks the three interleaved numbers into contiguous 5-bit sections of the returned int. The low 5 bits (bits 0-4) will store what was originallyindex1, the 5 bits above that (5-9) will store what was originallyindex2, and the 5 bits above that (10-14) will store what was originallyindex2. Source: and-what-happened blog post.- Parameters:
morton- a 15-bit Morton code, typically produced bymortonEncode3D(int, int, int)- Returns:
- a different encoding of the three 5-bit values, with bits 0-4, 5-9, and 10-14 storing the 3 indices
-
getXMoore3D
public static int getXMoore3D(int index, int n) Gets the x coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the x coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
getYMoore3D
public static int getYMoore3D(int index, int n) Gets the y coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the y coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
getZMoore3D
public static int getZMoore3D(int index, int n) Gets the z coordinate for a given index into the 16x16x(8*n) Moore curve. Expects indices to touch the following corners of the 16x16x(8*n) cube in this order, using x,y,z syntax: (0,0,0) (0,0,(8*n)) (0,16,(8*n)) (0,16,0) (16,16,0) (16,16,(8*n)) (16,0,(8*n)) (16,0,0)- Parameters:
index- the index into the 3D 16x16x(8*n) Moore Curve, must be less than 0x1000n- the number of 8-deep layers to use as part of the box shape this travels through- Returns:
- the z coordinate of the given distance traveled through the 3D 16x16x(8*n) Moore Curve
-
mortonEncode
public static int mortonEncode(int index1, int index2) Takes two 8-bit unsigned integers index1 and index2, and returns a Morton code, with interleaved index1 and index2 bits and index1 in the least significant bit. With this method, index1 and index2 can have up to 8 bits. This returns a 32-bit Morton code but only uses 16 bits, and will not encode information in the sign bit. Source: and-what-happened blog post.- Parameters:
index1- a non-negative integer using at most 8 bits, to be placed in the "x" slotsindex2- a non-negative integer using at most 8 bits, to be placed in the "y" slots- Returns:
- a Morton code that interleaves the two numbers as one 32-bit int, but only in 16 bits of it
-
mortonDecode
Takes a Morton code, with interleaved x and y bits and x in the least significant bit, and returns the Coord representing the same x, y position. This uses 16 bits of the Morton code and requires that the code is non-negative. Source: and-what-happened blog post.- Parameters:
morton- an int containing two interleaved numbers, from 0 to 255 each- Returns:
- a Coord matching the x and y extracted from the Morton code
-