Class Coord
java.lang.Object
com.github.yellowstonegames.grid.Coord
- All Implemented Interfaces:
com.github.tommyettinger.crux.Point2<Coord>, com.github.tommyettinger.crux.PointN<Coord>, com.github.tommyettinger.crux.PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>, com.github.tommyettinger.ds.PrimitiveCollection<Integer>, com.github.tommyettinger.ds.PrimitiveCollection.OfInt, PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>
public final class Coord
extends Object
implements com.github.tommyettinger.crux.Point2<Coord>, PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>, com.github.tommyettinger.ds.PrimitiveCollection.OfInt
A 2D coordinate with (constant) x and y fields. Coord objects are immutable; a single pool of Coord values, with
x and y each ranging from -3 to 255, is shared by all users of Coord (the upper limit of 255 can be increased as
needed). This pool helps reduce pressure on the garbage collector when many Coord values would have been created for
some purpose and quickly discarded; instead of creating a new Coord with a constructor, you use the static method
More on the Coord pool used by this class: Coords can't always be retrieved from the pool; Coord.get() constructs a new Coord if one of x or y is unusually large (greater than 255) or too negative (below -3). The upper limit of 255 is not a hard rule; you can increase the limit on the pool by calling
The x and y fields are internally
This implements
get(int, int), which retrieves an already-existing Coord from the pool if possible, and always returns a
usable Coord. This class has various instance methods, but none of them modify the current Coord; if they change
anything, they do so by returning another Coord with different x and y values via get(int, int).
More on the Coord pool used by this class: Coords can't always be retrieved from the pool; Coord.get() constructs a new Coord if one of x or y is unusually large (greater than 255) or too negative (below -3). The upper limit of 255 is not a hard rule; you can increase the limit on the pool by calling
expandPoolTo(int, int) or
expandPool(int, int), which cause more memory to be spent initially on storing Coords but can save memory
or ease GC pressure over the long term by preventing duplicate Coords from being created many times. The pool can
never shrink because allowing that would cause completely unpredictable results if existing Coords were in use, or
could easily cause crashes on Android after resuming an application that had previously shrunken the pool due to
platform quirks. Long story short, you should only expand the pool size when your game needs a larger set of 2D
points it will commonly use, and in many cases you shouldn't need to change it at all.
The x and y fields are internally
shorts, since most usage of Coord should use pooled Coord values, and there
isn't much of a possible way to store more than 32767x32767 (where 32767 is Short.MAX_VALUE) Coords in any
Java application due to limits on array size. There is also an immutable, precalculated result for
hashCode() to return without needing to recalculate anything. The precalculated hash won't overlap with the
hash for any other Coord as long as all Coord values have x and y each in the range from Short.MIN_VALUE to
Short.MAX_VALUE. Larger ranges than a 8192x8192 grid of Coord items tend to exhaust all of Java's heap
(using only Coord items), so supporting larger sizes isn't at all a priority.
This implements
Point2, allowing it to interoperate with some other libraries that also use the interfaces
from the library crux. A side effect of this is that using the
field x gets a short value, while calling x() uses the interface and gets a float.
If this causes problems in, for instance, Kotlin code, you could create an extension method that gets the type you
want and has the name you want.-
Nested Class Summary
Nested classes/interfaces inherited from interface com.github.tommyettinger.ds.PrimitiveCollection
com.github.tommyettinger.ds.PrimitiveCollection.OfBoolean, com.github.tommyettinger.ds.PrimitiveCollection.OfByte, com.github.tommyettinger.ds.PrimitiveCollection.OfChar, com.github.tommyettinger.ds.PrimitiveCollection.OfDouble, com.github.tommyettinger.ds.PrimitiveCollection.OfFloat, com.github.tommyettinger.ds.PrimitiveCollection.OfInt, com.github.tommyettinger.ds.PrimitiveCollection.OfLong, com.github.tommyettinger.ds.PrimitiveCollection.OfShort -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final com.github.tommyettinger.ds.support.util.PartialParser<Coord> A constant PartialParser that can read in thetoString()of a printed Coord to get that Coord back.final intAlso accessible viahashCode(), this is a precalculated hashCode() result.final shortThe x-coordinate.final shortThe y-coordinate (the ordinate) -
Method Summary
Modifier and TypeMethodDescriptionbooleanadd(int i) Always throws anUnsupportedOperationExceptionbecause Coord is fixed-size.Separately combines the x and y positions of this Coord and other, producing a different Coord as their "sum."Separately averages the x and y positions of this Coord with other, producing a different Coord as their "midpoint."static intcantorHashCode(int x, int y) Returns the int result of the Cantor pairing function for two int inputs.voidclear()booleancontains(int i) cpy()static Coorddecode(int code) This can take an int produced bysomeCoord.encode()and get the original Coord back out of it.static floatGets the angle in degrees to go between two Coords.intGets a variant hash code for this Coord; does not use the standard "auto-complete" style of hash that most IDEs will generate, but instead uses a specific technique based on the Rosenberg-Strong pairing function.floatdistance(float x2, float y2) Gets the distance from this Coord to the given x2,y2 Coord, as a float.floatGets the distance from this Coord to the given Coord, as a float.doubledistanceD(double x2, double y2) Gets the distance from this Coord to the given x2,y2 Coord, as a double.doubleGets the distance from this Coord to the given Coord, as a double.floatdistanceSq(float x2, float y2) Gets the squared distance from this Coord to the given x2,y2 Coord, as a float.floatdistanceSq(Coord co) Gets the squared distance from this Coord to the given Coord, as a float.doubledistanceSqD(double x2, double y2) Gets the squared distance from this Coord to the given x2,y2 Coord, as a double.doubledistanceSqD(Coord co) Gets the squared distance from this Coord to the given Coord, as a double.divide(float operand) Separately divides the x and y positions of this Coord by operand, truncating closer to 0 for non-integer x and y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and NaN are both possibilities).divide(int operand) Separately divides the x and y positions of this Coord by operand, producing a different Coord as their "quotient." If operand is 0, this will throw an exception, as dividing by 0 is expected to do.Separately divides the x and y positions of this Coord by other, producing a different Coord as their "quotient." If other has 0 for x or y, this will throw an exception, as dividing by 0 is expected to do.divideRounding(float operand) Separately divides the x and y positions of this Coord by operand, rounding to the nearest int for each of x and y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and NaN are both possibilities).floatintencode()Something like hashCode(), but reversible withCoord.decode().booleanstatic voidexpandPool(int xIncrease, int yIncrease) Enlarges the pool of cached Coords by the given amount of expansion for x and y.static voidexpandPoolTo(int width, int height) Enlarges the pool of cached Coords to the given width and height, and doesn't change a dimension if it would be reduced in size.booleanintget(int index) Gets the component at the specified index.static Coordget(int x, int y) static intGets the height of the pool used as a cache for Coords, not including negative Coords.static intGets the width of the pool used as a cache for Coords, not including negative Coords.Provided for compatibility with earlier code that used the AWT Point API.static intGets the height of the pool used as a cache for Coords, not including negative Coords.static intGets the width of the pool used as a cache for Coords, not including negative Coords.intgetX()intgetY()inthashCode()intA specialized hashing function that is meant to pack Coord items extremely densely in hash-based Maps or Sets, at the expense of any random-seeming quality in the hash.booleanisAdjacent(Coord c) booleanisWithin(int width, int height) Returns true if x is between 0 (inclusive) and width (exclusive) and y is between 0 (inclusive) and height (exclusive), false otherwise.booleanisWithinRectangle(int minX, int minY, int maxX, int maxY) Returns true if x is between minX (inclusive) and maxX (exclusive) and y is between minY (inclusive) and maxY (exclusive), false otherwise.com.github.tommyettinger.ds.support.util.IntIteratoriterator()floatlen2()lerp(com.github.tommyettinger.crux.Point2<?> end, float amountTraveled) Gets a (usually cached) Coord linearly-interpolated between this Coord andend, with the actual position relative to this based onamountTraveled.makeEven()Gets a Coord based off this instance but with odd values for x and/or y decreased to the nearest even numbermakeOdd()Gets a Coord based off this instance but with even values for x and/or y increased to the nearest odd number.minus(float operand) Separately subtracts operand from the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "difference."multiply(float operand) Separately multiplies the x and y positions of this Coord by operand, rounding to the nearest int for each of x and y and producing a different Coord as their "product."multiply(int operand) Separately multiplies the x and y positions of this Coord by operand, producing a different Coord as their "product."Separately multiplies the x and y positions of other from this Coord, producing a different Coord as their "product."booleanmutable()plus(float operand) Separately adds the x and y positions of this Coord to operand, rounding to the nearest int for each of x and y and producing a different Coord as their "sum."plus(int operand) Separately adds the x and y positions of this Coord to operand, producing a different Coord as their "sum." This is called "plus" and not "add" becausePrimitiveCollection.OfInt.add(int)was already used.static intpureEncode(int x, int y) An alternative to getting a Coord with Coord.get() only to encode() it as the next step.static floatGets the angle in radians to go between two Coords.booleanremove(int i) Always throws anUnsupportedOperationExceptionbecause Coord is fixed-size.static introsenbergStrongHashCode(int x, int y) A static version of a priorhashCode()method of this class, taking x and y as parameters instead of requiring a Coord object.static introsenbergStrongRandomizedHashCode(int x, int y) A static version of an earlierhashCode()method of this class, taking x and y as parameters instead of requiring a Coord object.scale(int i) scale(int i, int j) set(float nextX, float nextY) setAt(int index, int value) Sets the component at the specified index to the specified value, obtaining a Coord that has the requested value from the pool if possible.seti(int x, int y) setX(int x) setY(int y) setZero()static intsignedCantorHashCode(int x, int y) This is just likesignedRosenbergStrongMultiplyHashCode(int, int), but using the Cantor pairing function instead of the Rosenberg-Strong pairing function, and without the finalizing multiplication the other hash code uses.static intsignedRosenbergStrongHashCode(int x, int y) If x and y are validshortnumbers, then this will return a uniqueinthash code for those two.static CoordsignedRosenbergStrongInverse(int code) Given an int that may have been returned bysignedRosenbergStrongHashCode(int, int), this finds the Coord (asshort xandshort y) that would produce that int if passed tosignedRosenbergStrongHashCode(int, int).static intsignedRosenbergStrongMultiplyHashCode(int x, int y) If x and y are validshortnumbers, then this will return a uniqueinthash code for those two.static CoordsignedRosenbergStrongMultiplyInverse(int code) Given an int that may have been returned bysignedRosenbergStrongMultiplyHashCode(int, int), this finds the Coord (asshort xandshort y) that would produce that int if passed tosignedRosenbergStrongMultiplyHashCode(int, int).intsize()subtract(float operand) Separately subtracts operand from the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "difference."subtract(int operand) Separately subtracts operand from the x and y positions of this Coord, producing a different Coord as their "difference."Separately subtracts the x and y positions of other from this Coord, producing a different Coord as their "difference."times(float operand) Separately multiplies operand with the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "product."Gets theDirectionneeded to get totargetfrom this; typically this is more useful when target and this are adjacent (byisAdjacent(Coord)) since that should make it possible to go to target.toString()translate(int x, int y) Takes this Coord, adds x to its x and y to its y, and returns the Coord at that position.translateCapped(int x, int y, int width, int height) Takes this Coord, adds x to its x and y to its y, limiting x from 0 to width and limiting y from 0 to height, and returns the Coord at that position.static floatGets the angle in turns to go between two Coords.floatx()x(float nextX) intxi()xi(int next) static intxoroHashCode(int x, int y) An earlier hashCode() implementation used by this class, now standalone in case you want to replicate the results of the older code.floaty()y(float nextY) intyi()yi(int next) Methods inherited from interface com.github.tommyettinger.crux.Point2
rankMethods inherited from interface com.github.tommyettinger.crux.PointN
dst, isUnit, isUnit, isZero, isZero, len, norMethods inherited from interface PointNInt
interpolateMethods inherited from interface com.github.tommyettinger.ds.PrimitiveCollection
isEmpty, notEmptyMethods inherited from interface com.github.tommyettinger.ds.PrimitiveCollection.OfInt
addAll, addAll, addAll, addAll, addDense, addDense, addLegible, addLegible, addVarargs, appendTo, appendTo, containsAll, containsAll, containsAll, containsAll, containsAny, containsAny, containsAny, containsAny, denseAppendTo, equalContents, first, forEach, removeAll, removeAll, removeAll, removeAll, removeEach, removeEach, removeEach, removeEach, removeIf, retainAll, retainAll, retainAll, toArray, toArray, toDenseString, toDenseString, toString, toString, toString
-
Field Details
-
x
public final short xThe x-coordinate. -
y
public final short yThe y-coordinate (the ordinate) -
hash
public final transient int hashAlso accessible viahashCode(), this is a precalculated hashCode() result. It is only assigned when a Coord is first created. It uses a method of computing a hash value that won't collide in full (over all 32 bits) for any possible Coord values. Even using a smaller portion of the hash, if a hash table can fit 8192x8192 Coord values with load factor 0.5f, an appropriate mask will still not cause collisions here. This does not randomize the hash at all; it does do some work to allow negative-valued Coords to be used without frequent collisions.
The actual method used to assign this involves passing x and y to the Rosenberg-Strong pairing function, if both x and y are non-negative. The Rosenberg-Strong pairing function is discussed more here (a good introduction) and here (a more technical paper). If x is negative, this toggles every other bit using the mask0xAAAAAAAA; if y is negative, this toggles every other bit using the mask0x55555555(which is every bit not flipped by negative x).- See Also:
-
COORD_PARSER
A constant PartialParser that can read in thetoString()of a printed Coord to get that Coord back. This is mostly useful withEnhancedCollection.addLegible(String, String, PartialParser)and similar methods on Coord-based data structures.
-
-
Method Details
-
get
-
radians
Gets the angle in radians to go between two Coords. When only x is different andto.xis greater thanfrom.x, this returns 0. When only y is different andto.yis greater thanfrom.y, this returnsTrigTools.HALF_PI. When only x is different andto.xis less thanfrom.x, this returnsTrigTools.PI. When only y is different andto.yis less thanfrom.y, this returns negativeTrigTools.HALF_PI. In cases between these, the angle is between those values, except that values change from positiveTrigTools.PIto negativeTrigTools.PIas the angle crosses the y-axis. This can often return a negative angle. Keep in mind, "up" depends on how your code orients the y-axis, and SquidSquad generally defaults to positive y going toward the top of the screen, like in most textbook geometry.- Parameters:
from- the starting Coord to measure fromto- the ending Coord to measure to- Returns:
- the angle in counterclockwise radians from
fromtoto; 0 is to the right
-
degrees
Gets the angle in degrees to go between two Coords. When only x is different andto.xis greater thanfrom.x, this returns 0. When only y is different andto.yis greater thanfrom.y, this returns 90. When only x is different andto.xis less thanfrom.x, this returns 180. When only y is different andto.yis less thanfrom.y, this returns 270. In cases between these, the angle is between those values; it cannot be 360, but it can be very close. This never returns a negative angle. Keep in mind, "up" depends on how your code orients the y-axis, and SquidSquad generally defaults to positive y going toward the top of the screen, like in most textbook geometry.- Parameters:
from- the starting Coord to measure fromto- the ending Coord to measure to- Returns:
- the angle in counterclockwise degrees from
fromtoto; 0 is to the right
-
turns
Gets the angle in turns to go between two Coords. When only x is different andto.xis greater thanfrom.x, this returns 0f. When only y is different andto.yis greater thanfrom.y, this returns 0.25f. When only x is different andto.xis less thanfrom.x, this returns 0.5f. When only y is different andto.yis less thanfrom.y, this returns 0.75f. In cases between these, the angle is between those values; it cannot be 1f, but it can be very close. This never returns a negative angle. Keep in mind, "up" depends on how your code orients the y-axis, and SquidSquad generally defaults to positive y going toward the top of the screen, like in most textbook geometry.- Parameters:
from- the starting Coord to measure fromto- the ending Coord to measure to- Returns:
- the angle in counterclockwise turns from
fromtoto; 0 is to the right
-
getLocation
Provided for compatibility with earlier code that used the AWT Point API.- Returns:
- this Coord, without changes
-
translate
Takes this Coord, adds x to its x and y to its y, and returns the Coord at that position.- Parameters:
x- the amount of x distance to movey- the amount of y distance to move- Returns:
- a Coord (usually cached and not a new instance) that has been moved the specified distance
-
translateCapped
Takes this Coord, adds x to its x and y to its y, limiting x from 0 to width and limiting y from 0 to height, and returns the Coord at that position.- Parameters:
x- the amount of x distance to movey- the amount of y distance to movewidth- one higher than the maximum x value this can use; typically the length of an arrayheight- one higher than the maximum y value this can use; typically the length of an array- Returns:
- a Coord (usually cached and not a new instance) that has been moved the specified distance
-
floatingPoint
public boolean floatingPoint()- Specified by:
floatingPointin interfacecom.github.tommyettinger.crux.PointN<Coord>- Specified by:
floatingPointin interfacecom.github.tommyettinger.crux.PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>- Specified by:
floatingPointin interfacePointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>
-
get
public int get(int index) Gets the component at the specified index. Kotlin-compatible using square-bracket indexing. Getting index 1 gets y; anything else gets x. -
setAt
Sets the component at the specified index to the specified value, obtaining a Coord that has the requested value from the pool if possible. Setting index 1 sets y; anything else sets x. This can sometimes return the same Coord reference it was called upon (when the changed component already had the requested value), but it usually returns a different one.- Specified by:
setAtin interfacecom.github.tommyettinger.crux.PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>- Specified by:
setAtin interfacePointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>- Parameters:
index- which component to set, in ordervalue- the value to assign at index- Returns:
- a Coord retrieved from the pool with the given value at the given index
-
mutable
public boolean mutable()- Specified by:
mutablein interfacecom.github.tommyettinger.crux.PointN<Coord>
-
cpy
-
len2
public float len2()- Specified by:
len2in interfacecom.github.tommyettinger.crux.PointN<Coord>
-
set
-
setZero
-
sub
-
add
Separately combines the x and y positions of this Coord and other, producing a different Coord as their "sum."- Specified by:
addin interfacecom.github.tommyettinger.crux.PointN<Coord>- Parameters:
other- another Coord- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x + other.x; y = this.y + other.y
-
scl
-
div
-
dst2
-
plus
Separately adds the x and y positions of this Coord to operand, producing a different Coord as their "sum." This is called "plus" and not "add" becausePrimitiveCollection.OfInt.add(int)was already used.- Parameters:
operand- a value to add each of x and y to- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x + operand; y = this.y + operand
-
add
public boolean add(int i) Always throws anUnsupportedOperationExceptionbecause Coord is fixed-size. If you want to addito both components, useplus(int)orplus(float)instead.- Specified by:
addin interfacecom.github.tommyettinger.ds.PrimitiveCollection.OfInt- Parameters:
i- ignored- Returns:
- never returns
- Throws:
UnsupportedOperationException- always
-
remove
public boolean remove(int i) Always throws anUnsupportedOperationExceptionbecause Coord is fixed-size.- Specified by:
removein interfacecom.github.tommyettinger.ds.PrimitiveCollection.OfInt- Parameters:
i- ignored- Returns:
- never returns
- Throws:
UnsupportedOperationException- always
-
contains
public boolean contains(int i) - Specified by:
containsin interfacecom.github.tommyettinger.ds.PrimitiveCollection.OfInt
-
size
public int size()- Specified by:
sizein interfacecom.github.tommyettinger.ds.PrimitiveCollection<Integer>
-
iterator
public com.github.tommyettinger.ds.support.util.IntIterator iterator()- Specified by:
iteratorin interfacecom.github.tommyettinger.ds.PrimitiveCollection<Integer>- Specified by:
iteratorin interfacecom.github.tommyettinger.ds.PrimitiveCollection.OfInt
-
clear
public void clear()- Specified by:
clearin interfacecom.github.tommyettinger.ds.PrimitiveCollection<Integer>
-
plus
Separately adds the x and y positions of this Coord to operand, rounding to the nearest int for each of x and y and producing a different Coord as their "sum."- Specified by:
plusin interfacecom.github.tommyettinger.crux.PointN<Coord>- Parameters:
operand- a value to add each of x and y to- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x + operand; y = this.y + operand, with both x and y rounded accordingly
-
minus
Separately subtracts operand from the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "difference."- Specified by:
minusin interfacecom.github.tommyettinger.crux.PointN<Coord>- Parameters:
operand- a value to subtract from each of x and y- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x - operand; y = this.y - operand, with both x and y rounded accordingly
-
times
Separately multiplies operand with the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "product."- Specified by:
timesin interfacecom.github.tommyettinger.crux.PointN<Coord>- Parameters:
operand- a value to multiply with each of x and y- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x * operand; y = this.y * operand, with both x and y rounded accordingly
-
subtract
-
subtract
Separately subtracts operand from the x and y positions of this Coord, producing a different Coord as their "difference."- Parameters:
operand- a value to subtract from each of x and y- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x - operand; y = this.y - operand
-
subtract
Separately subtracts operand from the x and y positions of this Coord, rounding to the nearest int for each of x and y and producing a different Coord as their "difference."- Parameters:
operand- a value to subtract from each of x and y- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x - operand; y = this.y - operand, with both x and y rounded accordingly
-
multiply
-
multiply
Separately multiplies the x and y positions of this Coord by operand, producing a different Coord as their "product."- Parameters:
operand- a value to multiply each of x and y by- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x * operand; y = this.y * operand
-
multiply
Separately multiplies the x and y positions of this Coord by operand, rounding to the nearest int for each of x and y and producing a different Coord as their "product."- Parameters:
operand- a value to multiply each of x and y by- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x * operand; y = this.y * operand, with both x and y rounded accordingly
-
divide
Separately divides the x and y positions of this Coord by other, producing a different Coord as their "quotient." If other has 0 for x or y, this will throw an exception, as dividing by 0 is expected to do.- Parameters:
other- another Coord- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x / other.x; y = this.y / other.y
-
divide
Separately divides the x and y positions of this Coord by operand, producing a different Coord as their "quotient." If operand is 0, this will throw an exception, as dividing by 0 is expected to do.- Parameters:
operand- a value to divide each of x and y by- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x / operand; y = this.y / operand
-
divide
Separately divides the x and y positions of this Coord by operand, truncating closer to 0 for non-integer x and y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and NaN are both possibilities).- Specified by:
dividein interfacecom.github.tommyettinger.crux.PointN<Coord>- Parameters:
operand- a value to divide each of x and y by- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x / operand; y = this.y / operand, with both x and y rounded accordingly
-
divideRounding
Separately divides the x and y positions of this Coord by operand, rounding to the nearest int for each of x and y and producing a different Coord as their "quotient." If operand is 0.0, expect strange results (infinity and NaN are both possibilities).- Parameters:
operand- a value to divide each of x and y by- Returns:
- a Coord (usually cached and not a new instance) with
x = this.x / operand; y = this.y / operand, with both x and y rounded accordingly
-
average
-
translate
-
scale
- Parameters:
i- scale factor- Returns:
(x*i,y*i).
-
scale
- Parameters:
i- scale factor for xj- scale factor for y- Returns:
(x*i,y*j).
-
distance
public float distance(float x2, float y2) Gets the distance from this Coord to the given x2,y2 Coord, as a float.- Parameters:
x2- x of a different Coordy2- y of a different Coord- Returns:
- Euclidean distance from this Coord to the other given Coord, as a float
-
distance
Gets the distance from this Coord to the given Coord, as a float.- Parameters:
co- a different Coord- Returns:
- Euclidean distance from this Coord to the other given Coord, as a float
-
distanceSq
public float distanceSq(float x2, float y2) Gets the squared distance from this Coord to the given x2,y2 Coord, as a float.- Parameters:
x2- x of a different Coordy2- y of a different Coord- Returns:
- squared Euclidean distance from this Coord to the other given Coord, as a float
-
distanceSq
Gets the squared distance from this Coord to the given Coord, as a float.- Parameters:
co- a different Coord- Returns:
- squared Euclidean distance from this Coord to the other given Coord, as a float
-
distanceD
public double distanceD(double x2, double y2) Gets the distance from this Coord to the given x2,y2 Coord, as a double.- Parameters:
x2- x of a different Coordy2- y of a different Coord- Returns:
- Euclidean distance from this Coord to the other given Coord, as a double
-
distanceD
Gets the distance from this Coord to the given Coord, as a double.- Parameters:
co- a different Coord- Returns:
- Euclidean distance from this Coord to the other given Coord, as a double
-
distanceSqD
public double distanceSqD(double x2, double y2) Gets the squared distance from this Coord to the given x2,y2 Coord, as a double.- Parameters:
x2- x of a different Coordy2- y of a different Coord- Returns:
- squared Euclidean distance from this Coord to the other given Coord, as a double
-
distanceSqD
Gets the squared distance from this Coord to the given Coord, as a double.- Parameters:
co- a different Coord- Returns:
- squared Euclidean distance from this Coord to the other given Coord, as a double
-
makeEven
Gets a Coord based off this instance but with odd values for x and/or y decreased to the nearest even number- Returns:
- a Coord (probably from the pool) with even x and even y, changing (decrementing) only if they are odd
-
makeOdd
Gets a Coord based off this instance but with even values for x and/or y increased to the nearest odd number.- Returns:
- a Coord (probably from the pool) with odd x and odd y, changing (incrementing) only if they are even
-
isAdjacent
- Parameters:
c- another Coord that could be adjacent; must not be null- Returns:
- Whether
thisis adjacent toc. Not that a cell is not adjacent to itself with this method.
-
toGoTo
Gets theDirectionneeded to get totargetfrom this; typically this is more useful when target and this are adjacent (byisAdjacent(Coord)) since that should make it possible to go to target.
Internally, this delegates toDirection.toGoTo(Coord, Coord), and some code may prefer using the method in Direction instead of this one. Earlier versions of this code only worked for adjacent Coords, which seemed like an unnecessary limitation since Direction's version worked for any arguments.- Parameters:
target- a non-nullCoord- Returns:
- the direction to go from
thistotarget
-
isWithin
public boolean isWithin(int width, int height) Returns true if x is between 0 (inclusive) and width (exclusive) and y is between 0 (inclusive) and height (exclusive), false otherwise.- Parameters:
width- the upper limit on x to check, exclusiveheight- the upper limit on y to check, exclusive- Returns:
- true if this Coord is within the limits of width and height and has non-negative x and y
-
isWithinRectangle
public boolean isWithinRectangle(int minX, int minY, int maxX, int maxY) Returns true if x is between minX (inclusive) and maxX (exclusive) and y is between minY (inclusive) and maxY (exclusive), false otherwise.- Parameters:
minX- the lower limit on x to check, inclusiveminY- the lower limit on y to check, inclusivemaxX- the upper limit on x to check, exclusivemaxY- the upper limit on y to check, exclusive- Returns:
- true if this Coord is within the limits of the given parameters
-
getX
public int getX() -
setX
-
getY
public int getY() -
setY
-
toString
-
hashCode
-
signedRosenbergStrongHashCode
public static int signedRosenbergStrongHashCode(int x, int y) If x and y are validshortnumbers, then this will return a uniqueinthash code for those two. If either is not a valid short, this cannot be guaranteed to produce a unique result. If you compare the results for two nearby x,y points, the upper bits of the hash codes this produces will be more random than the lower bits. This helps avoid collisions in dense sets or maps of Coord.
The actual method this uses involves casting x and y to short, storing their signs, then passing them to the Rosenberg-Strong pairing function. The Rosenberg-Strong pairing function is discussed more here (a good introduction) and here (a more technical paper). This finishes by toggling alternating bits if x and/or y is negative, potentially toggling every bit if both are negative. UnlikesignedRosenbergStrongMultiplyHashCode(int, int), this does not finish by multiplying by a constant. You can always do so yourself, but you should useBitConversion.imul(int, int)if targeting GWT at all.
This is similar to the algorithm used to precalculate the hash returned byhashCode(). Unlike most of the other hashCode() variants here, this acts fine with negative inputs, and should still return random-enough hashes when x or y isn't in the short range (just not guaranteed to be unique).
Calculating this is branchless if calculatingMath.max(int, int)is branchless. This is true on modern desktop JVMs with sufficient optimization, and may be true on other platforms as well.- Parameters:
x- should usually be in the range for a valid short (fromShort.MIN_VALUEtoShort.MAX_VALUE)y- should usually be in the range for a valid short (fromShort.MIN_VALUEtoShort.MAX_VALUE)- Returns:
- an int hash code that will be unique for any combination of short x and short y
-
signedRosenbergStrongInverse
Given an int that may have been returned bysignedRosenbergStrongHashCode(int, int), this finds the Coord (asshort xandshort y) that would produce that int if passed tosignedRosenbergStrongHashCode(int, int).
Calculating this is branchless if calculatingMath.min(int, int)is branchless. This is true on modern desktop JVMs with sufficient optimization, and may be true on other platforms as well.
The inverse algorithm, like the forward algorithm, was modified slightly from this article by Steven Pigeon.- Parameters:
code- typically a result ofsignedRosenbergStrongHashCode(int, int)- Returns:
- a Coord that contains the x and y that would have been passed to
signedRosenbergStrongHashCode(int, int)
-
signedRosenbergStrongMultiplyHashCode
public static int signedRosenbergStrongMultiplyHashCode(int x, int y) If x and y are validshortnumbers, then this will return a uniqueinthash code for those two. If either is not a valid short, this cannot be guaranteed to produce a unique result. If you compare the results for two nearby x,y points, the upper bits of the hash codes this produces will be more random than the lower bits. This helps avoid collisions in dense sets or maps of Coord.
The actual method this uses involves passing x and y to the Rosenberg-Strong pairing function, then multiplying that by 0x9E3779B9, or -1640531527 in decimal. The Rosenberg-Strong pairing function is discussed more here (a good introduction) and here (a more technical paper). 0x9E3779B9 is used because it is (2 to the 32) divided by the golden ratio, and because of properties of the golden ratio, 0x9E3779B9 helps ensure "sub-random" bit patterns in its multiples. Because 0x9E3779B9 is odd, if every possible int is taken and multiplied by 0x9E3779B9, the full set of (2 to the 32) numbers will just be rearranged; nothing will collide.
This is the same as the algorithm used to precalculate the hash returned byhashCode(). Unlike most of the other hashCode() variants here, this acts fine with negative inputs, and should still return random-enough hashes when x or y isn't in the short range (just not guaranteed to be unique).
Calculating this is branchless if calculatingMath.max(int, int)is branchless. This is true on modern desktop JVMs with sufficient optimization, and may be true on other platforms as well.- Parameters:
x- should usually be in the range for a valid short (fromShort.MIN_VALUEtoShort.MAX_VALUE)y- should usually be in the range for a valid short (fromShort.MIN_VALUEtoShort.MAX_VALUE)- Returns:
- an int hash code that will be unique for any combination of short x and short y
-
signedRosenbergStrongMultiplyInverse
Given an int that may have been returned bysignedRosenbergStrongMultiplyHashCode(int, int), this finds the Coord (asshort xandshort y) that would produce that int if passed tosignedRosenbergStrongMultiplyHashCode(int, int).
Calculating this is branchless if calculatingMath.min(int, int)is branchless. This is true on modern desktop JVMs with sufficient optimization, and may be true on other platforms as well.
The inverse algorithm, like the forward algorithm, was modified from this article by Steven Pigeon.- Parameters:
code- typically a result ofsignedRosenbergStrongMultiplyHashCode(int, int)- Returns:
- a Coord that contains the x and y that would have been passed to
signedRosenbergStrongMultiplyHashCode(int, int)
-
signedCantorHashCode
public static int signedCantorHashCode(int x, int y) This is just likesignedRosenbergStrongMultiplyHashCode(int, int), but using the Cantor pairing function instead of the Rosenberg-Strong pairing function, and without the finalizing multiplication the other hash code uses. Like that hash code, this will produce different results for(x,y),(-x,y)(x,-y), and(-x,-y). You should see unique results if you give this only (x,y) points where each of x and y is between-23170and23169, inclusive. This is a smaller range thansignedRosenbergStrongMultiplyHashCode(int, int)guarantees uniqueness for, by over 9000 at each end.
Calculating this is always branchless.- Parameters:
x- should usually be in the range from-23170to23169y- should usually be in the range from-23170to23169- Returns:
- an int hash code that should be unique for any combination of short x and short y
-
denseHashCode
public int denseHashCode()Gets a variant hash code for this Coord; does not use the standard "auto-complete" style of hash that most IDEs will generate, but instead uses a specific technique based on the Rosenberg-Strong pairing function. This technique will generally return all low values before it returns high values, if small Coord components are hashed first. The bits of the results will not be especially random, but they won't collide much at all, so in this case we may not want the most-random hashes. It does much better when Coords are in the default pooled range of -3 or greater. The Rosenberg-Strong pairing function is discussed more here;.
This works best if the Coords hashed are within the pooled range, including negative values between -3 and -1. If There are no negative x or y values, this does not perform as well as it could, and will probably perform worse thanhashCode(). It probably performs worse than the precalculated hashCode() in general, too.- Returns:
- an int that should, for most different Coord values, be significantly different from the other hash codes
- See Also:
-
hastyHashCode
public int hastyHashCode()A specialized hashing function that is meant to pack Coord items extremely densely in hash-based Maps or Sets, at the expense of any random-seeming quality in the hash. This is simply the Cantor pairing function, and while it does not behave particularly well with negative x or negative y, it does very well at not wasting space or computation time in a hash table with Coord keys that are very densely packed. This will be slower than just callinghashCode()in most cases, though, because that method uses a precomputed value.
This can produce negative results for some negative x,y inputs, but usually produces small positive results when both x and y are small and positive, and large positive results if either x or y is even moderately large.
This is "hasty" because it is meant to be fast, but is no longer the fastest option, so it's just fairly fast and has perhaps-not-the-best quality possible. This is identical to callingcantorHashCode(int, int)on this Coord's x and y.- Returns:
- an int that should, for different non-negative Coord values, be at least a little different from other hash codes
-
cantorHashCode
public static int cantorHashCode(int x, int y) Returns the int result of the Cantor pairing function for two int inputs. This is a way of getting a unique int result for small enough x and y values, where "small enough" can safely be considered "between 0 and 23000." This can overflow if the sum of x and y is greater than 46340, so it can't reasonably deal with all int inputs. In that case it still produces a result, it just may be negative or be a duplicate of another hash result.- Parameters:
x- the x coordinate of the "imaginary Coord" to hashy- the y coordinate of the "imaginary Coord" to hash- Returns:
- the result of the Cantor pairing function on x and y
-
rosenbergStrongHashCode
public static int rosenbergStrongHashCode(int x, int y) A static version of a priorhashCode()method of this class, taking x and y as parameters instead of requiring a Coord object. Like that prior hashCode() method, this involves the close-to-optimal mathematical Rosenberg-Strong pairing function to distribute x and y without overlap until they get very large. The Rosenberg-Strong pairing function can be written simply as((x >= y) ? x * (x + 2) - y : y * y + x); it produces sequential results for a sequence of positive points traveling in square "shells" away from the origin. the algorithm is discussed more here; the only changes made here are adding 3 to x and y (to account for the minimum of -3 in most cases for a Coord).- Parameters:
x- the x coordinate of the "imaginary Coord" to hashy- the y coordinate of the "imaginary Coord" to hash- Returns:
- the equivalent to an older hashCode() of an "imaginary Coord"
-
rosenbergStrongRandomizedHashCode
public static int rosenbergStrongRandomizedHashCode(int x, int y) A static version of an earlierhashCode()method of this class, taking x and y as parameters instead of requiring a Coord object. Like the earlier hashCode() method, this involves the close-to-optimal mathematical Rosenberg-Strong pairing function to distribute x and y without overlap until they get very large. The Rosenberg-Strong pairing function can be written simply as((x >= y) ? x * (x + 2) - y : y * y + x); it produces sequential results for a sequence of positive points traveling in square "shells" away from the origin. the algorithm is discussed more here; the only changes made here are adding 3 to x and y (to account for the minimum of -3 in most cases for a Coord), and some finalizing steps that help randomize the upper bits of the hash code (the lower bits are quite non-random because they can't permit any gaps while optimizing collision rates). This method is "Randomized" because of these final steps, and they may slow it down as a hash code somewhat, but make the result more chaotic.- Parameters:
x- the x coordinate of the "imaginary Coord" to hashy- the y coordinate of the "imaginary Coord" to hash- Returns:
- the equivalent to the hashCode() of an "imaginary Coord"
-
xoroHashCode
public static int xoroHashCode(int x, int y) An earlier hashCode() implementation used by this class, now standalone in case you want to replicate the results of the older code. This uses only bitwise operations, which tend to be fairly fast on all platforms, and when used in a collection it has comparable collision rates to the current hashCode() method (very, very low rates), but if used for procedural generation it's simply terrible, with large blocks of nearby x,y points having identical values for several bits and all changes happening in a repetitive checkerboard pattern.- Parameters:
x- the x coordinate of the "imaginary Coord" to hashy- the y coordinate of the "imaginary Coord" to hash- Returns:
- the equivalent to the hashCode() of an "imaginary Coord"
-
encode
public int encode()Something like hashCode(), but reversible withCoord.decode(). Works for Coords between roughly -256 and 32000 in each of x and y, but will probably only decode to pooled Coords if x and y are both between -3 and 255 (inclusive for both).- Returns:
- an int as a unique code for this Coord
-
pureEncode
public static int pureEncode(int x, int y) An alternative to getting a Coord with Coord.get() only to encode() it as the next step. This doesn't create a Coord in the middle step. Can be decoded with Coord.decode() to get the (x,y) Coord.- Parameters:
x- the x position to encodey- the y position to encode- Returns:
- the coded int that a Coord at (x,y) would produce with encode()
-
decode
This can take an int produced bysomeCoord.encode()and get the original Coord back out of it. It works for all pooled Coords where the pool hasn't been expanded past about 32,000 in either dimension. It even works for Coords with negative x or y as well, if they are no lower than -256 in either dimension. This will almost certainly fail (producing a gibberish Coord that probably won't be pooled) on hashes produced by any other class, including subclasses of Coord.- Parameters:
code- an encoded int from a Coord, but not a subclass of Coord- Returns:
- the Coord that gave hash as its hashCode()
-
equals
-
getCacheWidth
public static int getCacheWidth()Gets the width of the pool used as a cache for Coords, not including negative Coords. Unless expandPool() has been called, this should be 256. Useful for finding the upper (exclusive) bound for x values that can be used efficiently in Coords. Requesting a Coord with a x greater than or equal to this value will result in a new Coord being allocated and not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld and in extreme cases may require more time garbage collecting than is normally necessary.- Returns:
- the width of the Coord cache, disregarding negative Coords
-
getCacheHeight
public static int getCacheHeight()Gets the height of the pool used as a cache for Coords, not including negative Coords. Unless expandPool() has been called, this should be 256. Useful for finding the upper (exclusive) bound for y values that can be used efficiently in Coords. Requesting a Coord with a y greater than or equal to this value will result in a new Coord being allocated and not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld and in extreme cases may require more time garbage collecting than is normally necessary.- Returns:
- the height of the Coord cache, disregarding negative Coords
-
getPoolWidth
public static int getPoolWidth()Gets the width of the pool used as a cache for Coords, not including negative Coords. Unless expandPool() has been called, this should be 256. Useful for finding the upper (exclusive) bound for x values that can be used efficiently in Coords. Requesting a Coord with a x greater than or equal to this value will result in a new Coord being allocated and not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld and in extreme cases may require more time garbage collecting than is normally necessary.
This is an alias forgetCacheWidth().- Returns:
- the width of the Coord cache, disregarding negative Coords
-
getPoolHeight
public static int getPoolHeight()Gets the height of the pool used as a cache for Coords, not including negative Coords. Unless expandPool() has been called, this should be 256. Useful for finding the upper (exclusive) bound for y values that can be used efficiently in Coords. Requesting a Coord with a y greater than or equal to this value will result in a new Coord being allocated and not cached, which may cause problems with code that expects the normal reference equality of Coords to be upheld and in extreme cases may require more time garbage collecting than is normally necessary.
This is an alias forgetCacheHeight().- Returns:
- the height of the Coord cache, disregarding negative Coords
-
expandPoolTo
public static void expandPoolTo(int width, int height) Enlarges the pool of cached Coords to the given width and height, and doesn't change a dimension if it would be reduced in size. Cached Coord values will be reused by Coord.get instead of re-allocated each time. The default pool allows Coords with x and y each between -3 and 255, inclusive, to be cached, and is considered to have width and height of 256 to begin with. Giving a width greater than 256 will allow Coords with x greater than 255 to be cached; likewise for height. If width or height is smaller than the current cache width or height, that dimension will not change, but the other still may if it is valid. You cannot shrink the pool size.- Parameters:
width- the new width for the pool of cached Coords; will be ignored if smaller than the current widthheight- the new height for the pool of cached Coords; will be ignored if smaller than the current height
-
expandPool
public static void expandPool(int xIncrease, int yIncrease) Enlarges the pool of cached Coords by the given amount of expansion for x and y. Cached Coord values will be reused by Coord.get instead of re-allocated each time. The default pool allows Coords with x and y each between -3 and 255, inclusive, to be cached, and this can increase the size in the positive direction. If either xIncrease or yIncrease is negative, this method returns immediately and does nothing else; the same is true of both arguments are zero. You cannot shrink the pool size.- Parameters:
xIncrease- the amount to increase cache's width byyIncrease- the amount to increase cache's height by
-
lerp
Gets a (usually cached) Coord linearly-interpolated between this Coord andend, with the actual position relative to this based onamountTraveled. If amountTraveled is 0, this simply returns a Coord equal to this; if amountTraveled is 1, this returns a Coord equal to end, and values in between 0 and 1 give Coords between this and end.- Specified by:
lerpin interfacecom.github.tommyettinger.crux.PointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>- Specified by:
lerpin interfacePointNInt<Coord, com.github.tommyettinger.crux.Point2<?>>- Parameters:
end- another Coord that acts as the "far" endpoint, where this is the "near" start pointamountTraveled- a float between 0 and 1 inclusive, with lower meaning closer to this, higher meaning closer to end- Returns:
- a Coord that is between this and end as long as amountTraveled is between 0 and 1
-
x
public float x()- Specified by:
xin interfacecom.github.tommyettinger.crux.Point2<Coord>
-
x
-
xi
public int xi()- Specified by:
xiin interfacecom.github.tommyettinger.crux.Point2<Coord>
-
xi
-
y
public float y()- Specified by:
yin interfacecom.github.tommyettinger.crux.Point2<Coord>
-
y
-
yi
public int yi()- Specified by:
yiin interfacecom.github.tommyettinger.crux.Point2<Coord>
-
yi
-
set
-
seti
-