Package com.github.tommyettinger.digital
Class MathTools
java.lang.Object
com.github.tommyettinger.digital.MathTools
Mathematical operations not provided by
Includes code that was originally part of the Uncommon Maths software package as Maths. Also includes code adapted from libGDX as their MathUtils class. There's also
java.lang.Math
.
Includes code that was originally part of the Uncommon Maths software package as Maths. Also includes code adapted from libGDX as their MathUtils class. There's also
cbrt(float)
by Marc B. Reynolds, building on the legendary fast inverse square root,
and a generalized bias/gain function, barronSpline(float, float, float)
, popularized by Jon Barron.
The fastFloor(float)
and fastCeil(float)
methods were devised by Riven on JavaGaming.org .
factorial(float)
and gamma(float)
are by T. J. Stieltjes.
The lerp methods that operate on angles are originally from MathUtils in libGDX, which credits Nathan Sweet.-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final float
Thefloat
value that is closer than any other to e, the base of the natural logarithms.static final float
2 to the -24 as a float; this is equal toMath.ulp(0.5f)
, and is the smallest non-zero distance possible between two results ofRandom.nextFloat()
.static final double
2 to the -53 as a float; this is equal toMath.ulp(0.5)
, and is the smallest non-zero distance possible between two results ofRandom.nextDouble()
.static final float
A float that is meant to be used as the smallest reasonable tolerance for methods likeisEqual(float, float, float)
.static final long[]
1275 negative, oddlong
values that are calculated using a generalization of the golden ratio and exponents of those generalizations.static final float
The famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
; this is the "most irrational" of irrational numbers, and has various useful properties.static final double
The famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
, as a double; this is the "most irrational" of irrational numbers, and has various useful properties.static final float
The inverse of the golden ratio,(1.0 - Math.sqrt(5.0)) * -0.5
orGOLDEN_RATIO - 1.0
; this also has various useful properties.static final double
The inverse of the golden ratio,(1.0 - Math.sqrt(5.0)) * -0.5
orGOLDEN_RATIO - 1.0
, as a double; this also has various useful properties.static final float
The famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
; this is the "most irrational" of irrational numbers, and has various useful properties.static final double
The famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
, as a double; this is the "most irrational" of irrational numbers, and has various useful properties.static final float
The conjugate of the golden ratio,(1.0 - Math.sqrt(5.0)) * 0.5
or1.0 - GOLDEN_RATIO
; this also has various useful properties.static final double
The conjugate of the golden ratio,(1.0 - Math.sqrt(5.0)) * 0.5
or1.0 - GOLDEN_RATIO
, as a double; this also has various useful properties.static final float
Thefloat
value that is closer than any other toMath.sqrt(2.0)
, the ratio of the hypotenuse of an isosceles right triangle to one of its legs.static final double
Thedouble
value that is closer than any other toMath.sqrt(2.0)
, the ratio of the hypotenuse of an isosceles right triangle to one of its legs.static final float
Thefloat
value that is closer than any other to1.0 / Math.sqrt(2.0)
, the inverse of the square root of 2.static final double
Thedouble
value that is closer than any other to1.0 / Math.sqrt(2.0)
, the inverse of the square root of 2.static final float
Thefloat
value that is closer than any other toMath.sqrt(3.0)
, the ratio of the diagonal length of a cube to its edge length.static final double
Thedouble
value that is closer than any other toMath.sqrt(3.0)
, the ratio of the diagonal length of a cube to its edge length.static final float
Thefloat
value that is closer than any other toMath.sqrt(5.0)
, which has various useful properties, such as appearing in many formulae involving the golden ratio which is of course chiefly due to being part of its calculation.static final double
Thedouble
value that is closer than any other toMath.sqrt(5.0)
, which has various useful properties, such as appearing in many formulae involving the golden ratio which is of course chiefly due to being part of its calculation. -
Method Summary
Modifier and TypeMethodDescriptionstatic double
barronSpline
(double x, double shape, double turning) A generalization on bias and gain functions that can represent both; this version is branch-less.static float
barronSpline
(float x, float shape, float turning) A generalization on bias and gain functions that can represent both; this version is branch-less.static int
boundedInt
(long state, int bound) Given a state that is typically random-seeming, this produces an int within a bounded range that is similarly random-seeming.static long
boundedLong
(long state, long innerBound, long outerBound) Given a state that is typically random-seeming, this produces a long within a bounded range that is similarly random-seeming.static float
cbrt
(float x) An approximation of the cube-root function for float inputs and outputs.static int
ceil
(double t) LikeMath.ceil(double)
, but returns an int.static int
ceil
(float value) Returns the smallest int greater than or equal to the specified float.static int
ceilPositive
(float value) Returns the smallest integer greater than or equal to the specified float.static double
clamp
(double value, double min, double max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.static float
clamp
(float value, float min, float max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.static int
clamp
(int value, int min, int max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.static long
clamp
(long value, long min, long max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.static double
cube
(double n) Returns the cube (third power) of its parameter.static float
cube
(float n) Returns the cube (third power) of its parameter.static double
factorial
(double x) A close approximation to the factorial function for real numbers, using an algorithm by T.static float
factorial
(float x) A close approximation to the factorial function for real numbers, using an algorithm by T.static int
fastCeil
(float t) LikeMath.ceil(double)
, but takes a float and returns an int.static int
fastFloor
(float t) LikeMath.floor(double)
, but takes a float and returns an int.static int
fibonacci
(int n) Binet's formula for the Fibonacci sequence, which is a closed-form expression where which each resulting value is the sum of the two proceeding values.static long
fibonacci
(long n) Binet's formula for the Fibonacci sequence, which is a closed-form expression where which each resulting value is the sum of the two proceeding values.static int
floor
(double t) LikeMath.floor(double)
, but returns an int.static int
floor
(float value) Returns the largest int less than or equal to the specified float.static int
floorPositive
(float value) Returns the largest int less than or equal to the specified float.static double
gamma
(double x) A close approximation to the gamma function for positive doubles, using an algorithm by T.static float
gamma
(float x) A close approximation to the gamma function for positive floats, using an algorithm by T.static long
greatestCommonDivisor
(long a, long b) Determines the greatest common divisor of a pair of natural numbers using the Euclidean algorithm.static double
invSqrt
(double x) Fast inverse square root, best known for its implementation in Quake III Arena.static float
invSqrt
(float x) Fast inverse square root, best known for its implementation in Quake III Arena.static boolean
isEqual
(double a, double b, double tolerance) Equivalent to libGDX's isEqual() method in MathUtils; this compares two doubles for equality and allows the given tolerance during comparison.static boolean
isEqual
(float a, float b) Equivalent to libGDX's isEqual() method in MathUtils; this compares two floats for equality and allows just enough tolerance to ignore a rounding error.static boolean
isEqual
(float a, float b, float tolerance) Equivalent to libGDX's isEqual() method in MathUtils; this compares two floats for equality and allows the given tolerance during comparison.static boolean
isPowerOfTwo
(int value) Returns true ifvalue
is a power of two or is equal toInteger.MIN_VALUE
; false otherwise.static long
isqrt
(long n) Integer square root (using floor), maintaining correct results even for very largelong
values.static boolean
isZero
(double value, double tolerance) Returns true if the value is zero.static boolean
isZero
(float value) Returns true if the value is zero (using the default tolerance,FLOAT_ROUNDING_ERROR
, as outer bound).static boolean
isZero
(float value, float tolerance) Returns true if the value is zero, using the given tolerance.static double
lerp
(double fromValue, double toValue, double progress) Linearly interpolates between fromValue to toValue on progress position.static float
lerp
(float fromValue, float toValue, float progress) Linearly interpolates between fromValue to toValue on progress position.static double
lerpAngle
(double fromRadians, double toRadians, double progress) Linearly interpolates between two angles in radians.static float
lerpAngle
(float fromRadians, float toRadians, float progress) Linearly interpolates between two angles in radians.static double
lerpAngleDeg
(double fromDegrees, double toDegrees, double progress) Linearly interpolates between two angles in degrees.static float
lerpAngleDeg
(float fromDegrees, float toDegrees, float progress) Linearly interpolates between two angles in degrees.static double
lerpAngleTurns
(double fromTurns, double toTurns, double progress) Linearly interpolates between two angles in turns.static float
lerpAngleTurns
(float fromTurns, float toTurns, float progress) Linearly interpolates between two angles in turns.static double
log
(double base, double arg) Calculate logarithms for arbitrary bases.static float
log
(float base, float value) Calculate logarithms for arbitrary bases.static float
log2
(float value) static long
longFloor
(double t) LikeMath.floor(double)
, but returns a long.static long
longFloor
(float t) LikeMath.floor(double)
, but takes a float and returns a long.static double
map
(double inRangeStart, double inRangeEnd, double outRangeStart, double outRangeEnd, double value) Linearly map a value from one range to another.static float
map
(float inRangeStart, float inRangeEnd, float outRangeStart, float outRangeEnd, float value) Linearly map a value from one range to another.static int
modularMultiplicativeInverse
(int a) Given any odd inta
, this finds another odd intb
such thata * b == 1
.static long
modularMultiplicativeInverse
(long a) Given any odd longa
, this finds another odd longb
such thata * b == 1L
.static int
nextPowerOfTwo
(int n) Returns the next higher power of two relative ton
, or n if it is already a power of two.static double
norm
(double rangeStart, double rangeEnd, double value) Linearly normalizes value from a range.static float
norm
(float rangeStart, float rangeEnd, float value) Linearly normalizes value from a range.static float
nthrt
(float x, float n) Returns the nth root of x.static double
probit
(double d) A way of taking a double in the (0.0, 1.0) range and mapping it to a Gaussian or normal distribution, so high inputs correspond to high outputs, and similarly for the low range.double
probitInverse
(double x) Inverse to theprobit(double)
function; takes a normal-distributed input and returns a value between 0.0 and 1.0, both inclusive.static long
raiseToPower
(int value, int power) Calculate the first argument raised to the power of the second.static double
remainder
(double op, double d) Like the modulo operator%
, but the result will always match the sign ofd
instead ofop
.static float
remainder
(float op, float d) Like the modulo operator%
, but the result will always match the sign ofd
instead ofop
.static int
round
(float value) Returns the closest integer to the specified float.static int
roundPositive
(float value) Returns the closest integer to the specified float.static double
square
(double n) Returns the square (second power) of its parameter.static float
square
(float n) Returns the square (second power) of its parameter.static double
sway
(double value) Very similar toTrigTools.sinTurns(double)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently.static float
sway
(float value) Very similar toTrigTools.sinTurns(float)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently.static double
swayCubic
(double value) Very similar toTrigTools.sinTurns(double)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently.static float
swayCubic
(float value) Very similar toTrigTools.sinTurns(float)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently.static double
swayTight
(double value) Takes any double and produces a double in the 0.0 to 1.0 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static float
swayTight
(float value) Takes any float and produces a float in the 0f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes.static double
truncate
(double n) Forces precision loss on the given double so very small fluctuations away from an integer will be erased.static float
truncate
(float n) Forces precision loss on the given float so very small fluctuations away from an integer will be erased.static double
zigzag
(double value) Takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range.static float
zigzag
(float value) Takes any float and produces a float in the -1f to 1f range, with similar inputs producing close to a consistent rate of up and down through the range.
-
Field Details
-
FLOAT_ROUNDING_ERROR
public static final float FLOAT_ROUNDING_ERRORA float that is meant to be used as the smallest reasonable tolerance for methods likeisEqual(float, float, float)
. This is sufficient if the rounding error is the result of one addition or subtraction between numbers smaller than 16 (closer to 0). More math operations or larger numbers can produce larger rounding errors; you can try multiplying this constant by, for instance, 64, and using that as the tolerance if you need precision with three-digit numbers (16 * 64 is 1024, so 0 to 999 should be precise there). A larger rounding error can introduce false-positive equivalence with very small inputs.- See Also:
-
EPSILON
public static final float EPSILON2 to the -24 as a float; this is equal toMath.ulp(0.5f)
, and is the smallest non-zero distance possible between two results ofRandom.nextFloat()
. Useful for converting a 24-bitint
orlong
value to a gradient between 0 and 1.- See Also:
-
EPSILON_D
public static final double EPSILON_D2 to the -53 as a float; this is equal toMath.ulp(0.5)
, and is the smallest non-zero distance possible between two results ofRandom.nextDouble()
. Useful for converting a 53-bitlong
value to a gradient between 0 and 1.- See Also:
-
E
public static final float EThefloat
value that is closer than any other to e, the base of the natural logarithms.- See Also:
-
ROOT2
public static final float ROOT2Thefloat
value that is closer than any other toMath.sqrt(2.0)
, the ratio of the hypotenuse of an isosceles right triangle to one of its legs.- See Also:
-
ROOT2_D
public static final double ROOT2_DThedouble
value that is closer than any other toMath.sqrt(2.0)
, the ratio of the hypotenuse of an isosceles right triangle to one of its legs.- See Also:
-
ROOT2_INVERSE
public static final float ROOT2_INVERSEThefloat
value that is closer than any other to1.0 / Math.sqrt(2.0)
, the inverse of the square root of 2.- See Also:
-
ROOT2_INVERSE_D
public static final double ROOT2_INVERSE_DThedouble
value that is closer than any other to1.0 / Math.sqrt(2.0)
, the inverse of the square root of 2.- See Also:
-
ROOT3
public static final float ROOT3Thefloat
value that is closer than any other toMath.sqrt(3.0)
, the ratio of the diagonal length of a cube to its edge length.- See Also:
-
ROOT3_D
public static final double ROOT3_DThedouble
value that is closer than any other toMath.sqrt(3.0)
, the ratio of the diagonal length of a cube to its edge length.- See Also:
-
ROOT5
public static final float ROOT5Thefloat
value that is closer than any other toMath.sqrt(5.0)
, which has various useful properties, such as appearing in many formulae involving the golden ratio which is of course chiefly due to being part of its calculation.- See Also:
-
ROOT5_D
public static final double ROOT5_DThedouble
value that is closer than any other toMath.sqrt(5.0)
, which has various useful properties, such as appearing in many formulae involving the golden ratio which is of course chiefly due to being part of its calculation.- See Also:
-
GOLDEN_RATIO
public static final float GOLDEN_RATIOThe famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
; this is the "most irrational" of irrational numbers, and has various useful properties.
The same asPHI
.- See Also:
-
PHI
public static final float PHIThe famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
; this is the "most irrational" of irrational numbers, and has various useful properties.
The same asGOLDEN_RATIO
.- See Also:
-
GOLDEN_RATIO_D
public static final double GOLDEN_RATIO_DThe famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
, as a double; this is the "most irrational" of irrational numbers, and has various useful properties.
The same asPHI_D
.- See Also:
-
PHI_D
public static final double PHI_DThe famous golden ratio,(1.0 + Math.sqrt(5.0)) * 0.5
, as a double; this is the "most irrational" of irrational numbers, and has various useful properties.
The same asGOLDEN_RATIO_D
.- See Also:
-
GOLDEN_RATIO_INVERSE
public static final float GOLDEN_RATIO_INVERSEThe inverse of the golden ratio,(1.0 - Math.sqrt(5.0)) * -0.5
orGOLDEN_RATIO - 1.0
; this also has various useful properties.- See Also:
-
GOLDEN_RATIO_INVERSE_D
public static final double GOLDEN_RATIO_INVERSE_DThe inverse of the golden ratio,(1.0 - Math.sqrt(5.0)) * -0.5
orGOLDEN_RATIO - 1.0
, as a double; this also has various useful properties.- See Also:
-
PSI
public static final float PSIThe conjugate of the golden ratio,(1.0 - Math.sqrt(5.0)) * 0.5
or1.0 - GOLDEN_RATIO
; this also has various useful properties.- See Also:
-
PSI_D
public static final double PSI_DThe conjugate of the golden ratio,(1.0 - Math.sqrt(5.0)) * 0.5
or1.0 - GOLDEN_RATIO
, as a double; this also has various useful properties.- See Also:
-
GOLDEN_LONGS
public static final long[] GOLDEN_LONGS1275 negative, oddlong
values that are calculated using a generalization of the golden ratio and exponents of those generalizations. Mostly, these are useful because they are all 64-bit constants that have an irrational-number-like pattern to their bits, which makes them pretty much all useful as increments for large counters (also called Weyl sequences) and also sometimes as multipliers for data that should be somewhat random. The earlier numbers in the array are closer to the bit patterns of irrational numbers. Note that these are not at all uniformly-distributed, and should not be used for tasks where random negative longs must be uniform. See Martin Roberts' blog post for more information on how these were constructed. This can be organized into groups of increasing size -- 1 number from the 1D sequence in that post, 2 numbers from the 2D sequence, 3 numbers from the 3D sequence, etc.
-
-
Method Details
-
raiseToPower
public static long raiseToPower(int value, int power) Calculate the first argument raised to the power of the second. This method only supports non-negative powers.- Parameters:
value
- The number to be raised.power
- The exponent (must be positive).- Returns:
value
raised topower
.
-
log
public static double log(double base, double arg) Calculate logarithms for arbitrary bases.- Parameters:
base
- The base for the logarithm.arg
- The value to calculate the logarithm for.- Returns:
- The log of
arg
in the specifiedbase
.
-
log
public static float log(float base, float value) Calculate logarithms for arbitrary bases.- Parameters:
base
- the logarithm base to usevalue
- what value to get the logarithm of, using the given base- Returns:
- the logarithm of value with the given base
-
log2
public static float log2(float value) - Parameters:
value
- what value to get the logarithm of, using base 2- Returns:
- the logarithm of value with base 2
-
isEqual
public static boolean isEqual(double a, double b, double tolerance) Equivalent to libGDX's isEqual() method in MathUtils; this compares two doubles for equality and allows the given tolerance during comparison. An example is0.3 - 0.2 == 0.1
vs.isEqual(0.3 - 0.2, 0.1, 0.000001)
; the first is incorrectly false, while the second is correctly true.- Parameters:
a
- the first float to compareb
- the second float to comparetolerance
- the maximum difference between a and b permitted for this to return true, inclusive- Returns:
- true if a and b have a difference less than or equal to tolerance, or false otherwise.
-
isEqual
public static boolean isEqual(float a, float b) Equivalent to libGDX's isEqual() method in MathUtils; this compares two floats for equality and allows just enough tolerance to ignore a rounding error. An example is0.3f - 0.2f == 0.1f
vs.isEqual(0.3f - 0.2f, 0.1f)
; the first is incorrectly false, while the second is correctly true. This usesFLOAT_ROUNDING_ERROR
as its tolerance.- Parameters:
a
- the first float to compareb
- the second float to compare- Returns:
- true if a and b are equal or extremely close to equal, or false otherwise.
-
isEqual
public static boolean isEqual(float a, float b, float tolerance) Equivalent to libGDX's isEqual() method in MathUtils; this compares two floats for equality and allows the given tolerance during comparison. An example is0.3f - 0.2f == 0.1f
vs.isEqual(0.3f - 0.2f, 0.1f, 0.000001f)
; the first is incorrectly false, while the second is correctly true. SeeFLOAT_ROUNDING_ERROR
for advice on choosing a value for tolerance.- Parameters:
a
- the first float to compareb
- the second float to comparetolerance
- the maximum difference between a and b permitted for this to return true, inclusive- Returns:
- true if a and b have a difference less than or equal to tolerance, or false otherwise.
-
clamp
public static int clamp(int value, int min, int max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.
Note that it can often be just as easy to directly call the same code this calls, while being slightly friendlier to inlining in large methods:Math.min(Math.max(value, min), max)
.- Parameters:
value
- The value to check.min
- The minimum permitted value.max
- The maximum permitted value.- Returns:
value
if it is between the specified limits,min
if the value is too low, ormax
if the value is too high.
-
clamp
public static long clamp(long value, long min, long max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.
Note that it can often be just as easy to directly call the same code this calls, while being slightly friendlier to inlining in large methods:Math.min(Math.max(value, min), max)
.- Parameters:
value
- The value to check.min
- The minimum permitted value.max
- The maximum permitted value.- Returns:
value
if it is between the specified limits,min
if the value is too low, ormax
if the value is too high.
-
clamp
public static double clamp(double value, double min, double max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.
Note that it can often be just as easy to directly call the same code this calls, while being slightly friendlier to inlining in large methods:Math.min(Math.max(value, min), max)
.- Parameters:
value
- The value to check.min
- The minimum permitted value.max
- The maximum permitted value.- Returns:
value
if it is between the specified limits,min
if the value is too low, ormax
if the value is too high.
-
clamp
public static float clamp(float value, float min, float max) If the specified value is not greater than or equal to the specified minimum and less than or equal to the specified maximum, adjust it so that it is.
Note that it can often be just as easy to directly call the same code this calls, while being slightly friendlier to inlining in large methods:Math.min(Math.max(value, min), max)
.- Parameters:
value
- The value to check.min
- The minimum permitted value.max
- The maximum permitted value.- Returns:
value
if it is between the specified limits,min
if the value is too low, ormax
if the value is too high.
-
remainder
public static float remainder(float op, float d) Like the modulo operator%
, but the result will always match the sign ofd
instead ofop
.- Parameters:
op
- the dividend; negative values are permitted and wrap instead of producing negative resultsd
- the divisor; if this is negative then the result will be negative, otherwise it will be positive- Returns:
- the remainder of the division of op by d, with a sign matching d
-
remainder
public static double remainder(double op, double d) Like the modulo operator%
, but the result will always match the sign ofd
instead ofop
.- Parameters:
op
- the dividend; negative values are permitted and wrap instead of producing negative resultsd
- the divisor; if this is negative then the result will be negative, otherwise it will be positive- Returns:
- the remainder of the division of op by d, with a sign matching d
-
greatestCommonDivisor
public static long greatestCommonDivisor(long a, long b) Determines the greatest common divisor of a pair of natural numbers using the Euclidean algorithm. This method only works with natural numbers. If negative integers are passed in, the absolute values will be used. The return value is always positive.- Parameters:
a
- The first value.b
- The second value.- Returns:
- The greatest common divisor.
-
modularMultiplicativeInverse
public static int modularMultiplicativeInverse(int a) Given any odd inta
, this finds another odd intb
such thata * b == 1
. Note that this is now GWT-compatible thanks toBitConversion.imul(int, int)
, though this is unlikely to matter much.- Parameters:
a
- any odd int; note that even numbers do not have inverses modulo 2 to the 32- Returns:
- the multiplicative inverse of
a
modulo 4294967296 (or, 2 to the 32)
-
modularMultiplicativeInverse
public static long modularMultiplicativeInverse(long a) Given any odd longa
, this finds another odd longb
such thata * b == 1L
.- Parameters:
a
- any odd long; note that even numbers do not have inverses modulo 2 to the 64- Returns:
- the multiplicative inverse of
a
modulo 18446744073709551616 (or, 2 to the 64)
-
isqrt
public static long isqrt(long n) Integer square root (using floor), maintaining correct results even for very largelong
values. This version treats negative inputs as unsigned and returns positive square roots for them (these are usually large).
This is based on code used by Python, but isn't identical. Notably, this doesn't branch except in the for loop, and it handles negative inputs differently.- Parameters:
n
- along
value that will be treated as if unsigned- Returns:
- the square root of n, rounded down to the next lower
long
if the result isn't already along
-
cbrt
public static float cbrt(float x) An approximation of the cube-root function for float inputs and outputs. This can be about twice as fast asMath.cbrt(double)
. It correctly returns negative results when given negative inputs.
Has very low relative error (less than 1E-9) when inputs are uniformly distributed between -512 and 512, and absolute mean error of less than 1E-6 in the same scenario. Uses a bit-twiddling method similar to one presented in Hacker's Delight and also used in early 3D graphics (see Wikipedia for more, but this code approximates cbrt(x) and not 1/sqrt(x)). This specific code was originally by Marc B. Reynolds, posted in his "Stand-alone-junk" repo .
If you need to work with doubles, or need higher precision, useMath.cbrt(double)
.- Parameters:
x
- any finite float to find the cube root of- Returns:
- the cube root of x, approximated
-
nthrt
public static float nthrt(float x, float n) Returns the nth root of x. Any values withinFLOAT_ROUNDING_ERROR
of an int are rounded to that int to reduce the likelihood of floating-point error adversely affecting the result.
For a detailed description of how this function handles negative roots and roots of negative numbers, refer to the documentation forMath.pow(double, double)
. This implementation starts by callingMath.pow(x, 1f / n)
, so consider the documentation in Math for the reciprocal of the power.
Unlikecbrt(float)
, this is not an approximation, and isn't any faster than calling Math.pow() with the reciprocal of the power. Its advantage is in precision when integer results are mathematically correct, but Math won't calculate them correctly on its own.- Parameters:
x
- a number to find the nth root ofn
- the degree of the root; may be negative or non-integer- Returns:
- a number which, when raised to the power n, yields x
-
invSqrt
public static float invSqrt(float x) Fast inverse square root, best known for its implementation in Quake III Arena. This is an algorithm that estimates thefloat
value of 1/sqrt(x). It has comparable performance to the more-straightforward1f/(float)Math.sqrt(x)
on HotSpot JDKs, but this method outperforms the Math-based approach by over 40% on GraalVM 17. Some other platforms, such as Android and GWT, may have similar or very different performance relative to using Math, so if you expect to use this method often, you should test it in your app on the platforms you target. Precision will always be best with Math.
It is often used for vector normalization, i.e. scaling it to a length of 1. For example, it can be used to compute angles of incidence and reflection for lighting and shading.
For more information, see Wikipedia- Parameters:
x
- a non-negative finite float to find the inverse square root of- Returns:
- the inverse square root of x, approximated
-
invSqrt
public static double invSqrt(double x) Fast inverse square root, best known for its implementation in Quake III Arena. This is an algorithm that estimates thedouble
value of 1/sqrt(x). It has comparable performance to the more-straightforward1.0/Math.sqrt(x)
on HotSpot JDKs, but this method may outperform the Math-based approach on GraalVM 17 (the float version,invSqrt(float)
, does so by 40% or more). Some other platforms, such as Android and GWT, may have similar or very different performance relative to using Math, so if you expect to use this method often, you should test it in your app on the platforms you target. Precision will always be best with Math.
It is often used for vector normalization, i.e. scaling it to a length of 1. For example, it can be used to compute angles of incidence and reflection for lighting and shading.
For more information, see Wikipedia- Parameters:
x
- a non-negative finite double to find the inverse square root of- Returns:
- the inverse square root of x, approximated
-
barronSpline
public static float barronSpline(float x, float shape, float turning) A generalization on bias and gain functions that can represent both; this version is branch-less. This is based on this micro-paper by Jon Barron, which generalizes the earlier bias and gain rational functions by Schlick. The second and final page of the paper has useful graphs of what the s (shape) and t (turning point) parameters do; shape should be 0 or greater, while turning must be between 0 and 1, inclusive. This effectively combines two different curving functions so that they continue into each other when x equals turning. The shape parameter will cause this to imitate "smoothstep-like" splines when greater than 1 (where the values ease into their starting and ending levels), or to be the inverse when less than 1 (where values start like square root does, taking off very quickly, but also end like square does, landing abruptly at the ending level). You should only give x values between 0 and 1, inclusive.- Parameters:
x
- progress through the spline, from 0 to 1, inclusiveshape
- must be greater than or equal to 0; values greater than 1 are "normal interpolations"turning
- a value between 0.0 and 1.0, inclusive, where the shape changes- Returns:
- a float between 0 and 1, inclusive
-
barronSpline
public static double barronSpline(double x, double shape, double turning) A generalization on bias and gain functions that can represent both; this version is branch-less. This is based on this micro-paper by Jon Barron, which generalizes the earlier bias and gain rational functions by Schlick. The second and final page of the paper has useful graphs of what the s (shape) and t (turning point) parameters do; shape should be 0 or greater, while turning must be between 0 and 1, inclusive. This effectively combines two different curving functions so that they continue into each other when x equals turning. The shape parameter will cause this to imitate "smoothstep-like" splines when greater than 1 (where the values ease into their starting and ending levels), or to be the inverse when less than 1 (where values start like square root does, taking off very quickly, but also end like square does, landing abruptly at the ending level). You should only give x values between 0 and 1, inclusive.- Parameters:
x
- progress through the spline, from 0 to 1, inclusiveshape
- must be greater than or equal to 0; values greater than 1 are "normal interpolations"turning
- a value between 0.0 and 1.0, inclusive, where the shape changes- Returns:
- a double between 0 and 1, inclusive
-
probit
public static double probit(double d) A way of taking a double in the (0.0, 1.0) range and mapping it to a Gaussian or normal distribution, so high inputs correspond to high outputs, and similarly for the low range. This is centered on 0.0 and its standard deviation seems to be 1.0 (the same asRandom.nextGaussian()
). If this is given an input of 0.0 or less, it returns -38.5, which is slightly less than the result when givenDouble.MIN_VALUE
. If it is given an input of 1.0 or more, it returns 38.5, which is significantly larger than the result when given the largest double less than 1.0 (this value is further from 1.0 thanDouble.MIN_VALUE
is from 0.0). If givenDouble.NaN
, it returns whateverMath.copySign(double, double)
returns for the arguments38.5, Double.NaN
, which is implementation-dependent. It uses an algorithm by Peter John Acklam, as implemented by Sherali Karimov. Original source. Information on the algorithm. Wikipedia's page on the probit function may help, but is more likely to just be confusing.
Acklam's algorithm and Karimov's implementation are both quite fast. This appears faster when generating Gaussian-distributed numbers than using either the Box-Muller Transform or Marsaglia's Polar Method, though it isn't as precise and can't produce as extreme min and max results in the extreme cases they should appear. If given a typical uniform randomdouble
that's exclusive on 1.0, it won't produce a result higher than8.209536145151493
, and will only produce results of at least-8.209536145151493
if 0.0 is excluded from the inputs (if 0.0 is an input, the result is-38.5
).
This can be used both as an optimization for generating Gaussian random values, and as a way of generating Gaussian values that match a pattern present in the inputs (which you could have by using a sub-random sequence as the input, such as those produced by a van der Corput, Halton, Sobol or R2 sequence). Most methods of generating Gaussian values (e.g. Box-Muller and Marsaglia polar) do not have any way to preserve a particular pattern.- Parameters:
d
- should be between 0 and 1, exclusive, but other values are tolerated- Returns:
- a normal-distributed double centered on 0.0; all results will be between -38.5 and 38.5, both inclusive
- See Also:
-
probitInverse
public double probitInverse(double x) Inverse to theprobit(double)
function; takes a normal-distributed input and returns a value between 0.0 and 1.0, both inclusive. This is based on a scaled error function approximation; the original approximation has a maximum error of3.0e-7
, and scaling it shouldn't change that too drastically. The CDF of the normal distribution is essentially the same as this method.
Equivalent to a scaled error function from Abramowitz and Stegun, 1964; equation 7.1.27 . See Wikipedia.- Parameters:
x
- any finite double, typically normal-distributed but not necessarily- Returns:
- a double between 0 and 1, inclusive
-
nextPowerOfTwo
public static int nextPowerOfTwo(int n) Returns the next higher power of two relative ton
, or n if it is already a power of two. This returns 2 if n is any value less than 2 (including negative numbers, but also 1, which is a power of two).- Parameters:
n
- the lower bound for the result- Returns:
- the next higher power of two that is greater than or equal to n
-
isPowerOfTwo
public static boolean isPowerOfTwo(int value) Returns true ifvalue
is a power of two or is equal toInteger.MIN_VALUE
; false otherwise.- Parameters:
value
- any int- Returns:
- true if
value
is a power of two (when treated as unsigned)
-
gamma
public static double gamma(double x) A close approximation to the gamma function for positive doubles, using an algorithm by T. J. Stieltjes. Source here. This is exactly equivalent toMathExtras.factorial(x - 1.0)
.- Parameters:
x
- a real number; should usually be positive- Returns:
- the approximate gamma of the given x
-
factorial
public static double factorial(double x) A close approximation to the factorial function for real numbers, using an algorithm by T. J. Stieltjes. This performs a variable number of multiplications that starts at 1 when x is between 5 and 6, and requires more multiplications the lower x goes (to potentially many if x is, for instance, -1000.0, which would need 1006 multiplications per call). As such, you should try to call this mostly on x values that are positive or have a low magnitude. Source here.- Parameters:
x
- a real number; should not be both large and negative- Returns:
- the generalized factorial of the given x
-
gamma
public static float gamma(float x) A close approximation to the gamma function for positive floats, using an algorithm by T. J. Stieltjes. Source here. This is exactly equivalent toMathExtras.factorial(x - 1f)
.
This does all of its math on doubles internally and only casts to float at the end.- Parameters:
x
- a real number; should usually be positive- Returns:
- the approximate gamma of the given x
-
factorial
public static float factorial(float x) A close approximation to the factorial function for real numbers, using an algorithm by T. J. Stieltjes. This performs a variable number of multiplications that starts at 1 when x is between 5 and 6, and requires more multiplications the lower x goes (to potentially many if x is, for instance, -1000.0, which would need 1006 multiplications per call). As such, you should try to call this mostly on x values that are positive or have a low magnitude. Source here.
This does all of its math on doubles internally and only casts to float at the end.- Parameters:
x
- a real number; should not be both large and negative- Returns:
- the generalized factorial of the given x
-
fibonacci
public static int fibonacci(int n) Binet's formula for the Fibonacci sequence, which is a closed-form expression where which each resulting value is the sum of the two proceeding values. This has several useful applications, such as finding values within Pascal's triangle, which is itself useful in various areas of mathematics involving polynomial functions.
Negative inputs are allowed here, but may behave differently than positive inputs. When given non-negative integer inputs, this is only correct for inputs from 0 to 46 inclusive; the largest Fibonacci number this can correctly calculate is 1836311903, given an input of 46. You can get a larger range of values by passing along
input tofibonacci(long)
.
For more information see Wikipedia. This does not use the exact constant values in the "Computation by rounding" section, because minuscule adjustments to those constants proved to counterbalance accrued floating-point error for a few more inputs.- Parameters:
n
- an int index; should be less than 47- Returns:
- the Fibonacci number at index n, as an int
-
fibonacci
public static long fibonacci(long n) Binet's formula for the Fibonacci sequence, which is a closed-form expression where which each resulting value is the sum of the two proceeding values. This has several useful applications, such as finding values within Pascal's triangle, which is itself useful in various areas of mathematics involving polynomial functions.
Negative inputs are allowed here, but may behave differently than positive inputs. When given non-negative integer inputs, this is only correct for inputs from 0 to 77 inclusive; the largest Fibonacci number this can correctly calculate is 5527939700884757, given an input of 77. This means that all Fibonacci numbers that can be stored in a non-negativeint
can be produced by this method, as well as a substantial amount of non-negativelong
Fibonacci numbers. If you only have inputs that are less than 47, and you wantint
results, you can usefibonacci(int)
instead.
For more information see Wikipedia. This does not use the exact constant values in the "Computation by rounding" section, because minuscule adjustments to those constants proved to counterbalance accrued floating-point error for a few more inputs.- Parameters:
n
- a long index; should be less than 78- Returns:
- the Fibonacci number at index n, as a long
-
square
public static float square(float n) Returns the square (second power) of its parameter. Purely here for convenience.- Parameters:
n
- any float- Returns:
n * n
-
square
public static double square(double n) Returns the square (second power) of its parameter. Purely here for convenience.- Parameters:
n
- any double- Returns:
n * n
-
cube
public static float cube(float n) Returns the cube (third power) of its parameter. Purely here for convenience.- Parameters:
n
- any float- Returns:
n * n * n
-
cube
public static double cube(double n) Returns the cube (third power) of its parameter. Purely here for convenience.- Parameters:
n
- any double- Returns:
n * n * n
-
longFloor
public static long longFloor(double t) LikeMath.floor(double)
, but returns a long. Doesn't consider "weird doubles" like INFINITY and NaN. This is only faster than(long)Math.floor(t)
on Java 8 for supported desktop platforms.- Parameters:
t
- the double to find the floor for- Returns:
- the floor of t, as a long
-
longFloor
public static long longFloor(float t) LikeMath.floor(double)
, but takes a float and returns a long. Doesn't consider "weird floats" like INFINITY and NaN. This is only faster than(long)Math.floor(t)
on Java 8 for supported desktop platforms.- Parameters:
t
- the double to find the floor for- Returns:
- the floor of t, as a long
-
floor
public static int floor(double t) LikeMath.floor(double)
, but returns an int. Doesn't consider "weird doubles" like INFINITY and NaN. This is only faster than(int)Math.floor(t)
on Java 8 for supported desktop platforms.- Parameters:
t
- the float to find the floor for- Returns:
- the floor of t, as an int
-
fastFloor
public static int fastFloor(float t) LikeMath.floor(double)
, but takes a float and returns an int. Doesn't consider "weird floats" like INFINITY and NaN. This method will only properly floor floats from-16384
toInteger.MAX_VALUE - 16384
, or2147467263
. Unlikefloor(double)
,longFloor(float)
, andlongFloor(double)
, this is significantly faster than(int)Math.floor(t)
.
Taken from libGDX MathUtils.- Parameters:
t
- a float from -16384 to 2147467263 (both inclusive)- Returns:
- the floor of t, as an int
-
ceil
public static int ceil(double t) LikeMath.ceil(double)
, but returns an int. Doesn't consider "weird doubles" like INFINITY and NaN. This is only faster than(int)Math.ceil(t)
on Java 8 for supported desktop platforms.- Parameters:
t
- the float to find the ceiling for- Returns:
- the ceiling of t, as an int
-
fastCeil
public static int fastCeil(float t) LikeMath.ceil(double)
, but takes a float and returns an int. Doesn't consider "weird floats" like INFINITY and NaN. This method will only properly ceil floats from-16384
toInteger.MAX_VALUE - 16384
, or2147467263
. Unlikeceil(float)
, this is significantly faster than(int)Math.ceil(t)
.- Parameters:
t
- the float to find the ceiling for- Returns:
- the ceiling of t, as an int
-
floor
public static int floor(float value) Returns the largest int less than or equal to the specified float. Doesn't consider "weird floats" like INFINITY and NaN. This is only faster than(int)Math.floor(t)
on Java 8 for supported desktop platforms.
Taken from libGDX MathUtils.- Parameters:
value
- any float- Returns:
- the floor of value, as an int
-
floorPositive
public static int floorPositive(float value) Returns the largest int less than or equal to the specified float. This method will only properly floor floats that are positive. Note, this method simply casts the float to int.- Parameters:
value
- any positive float
-
ceil
public static int ceil(float value) Returns the smallest int greater than or equal to the specified float. Doesn't consider "weird floats" like INFINITY and NaN. This is only faster than(int)Math.ceil(t)
on Java 8 for supported desktop platforms.- Parameters:
value
- a float from -(2^14) to (Float.MAX_VALUE - 2^14)
-
ceilPositive
public static int ceilPositive(float value) Returns the smallest integer greater than or equal to the specified float. This method will only properly ceil floats that are positive.- Parameters:
value
- any positive float
-
round
public static int round(float value) Returns the closest integer to the specified float. This method will only properly round floats from -(2^14) to (Float.MAX_VALUE - 2^14).- Parameters:
value
- a float from -(2^14) to (Float.MAX_VALUE - 2^14)
-
roundPositive
public static int roundPositive(float value) Returns the closest integer to the specified float. This method will only properly round floats that are positive.- Parameters:
value
- any positive float
-
truncate
public static float truncate(float n) Forces precision loss on the given float so very small fluctuations away from an integer will be erased. This is meant primarily for cleaning up floats, so they can be presented without needing scientific notation. It leaves about 3 decimal digits after the point intact, and should make any digits after that simply 0.- Parameters:
n
- any float, but typically a fairly small one (between -8 and 8, as a guideline)- Returns:
n
with its 13 least significant bits effectively removed
-
truncate
public static double truncate(double n) Forces precision loss on the given double so very small fluctuations away from an integer will be erased. This is meant primarily for cleaning up doubles, so they can be presented without needing scientific notation. It leaves about 3 decimal digits after the point intact, and should make any digits after that simply 0.- Parameters:
n
- any double, but typically a fairly small one (between -8 and 8, as a guideline)- Returns:
n
with its 42 least significant bits effectively removed
-
lerp
public static float lerp(float fromValue, float toValue, float progress) Linearly interpolates between fromValue to toValue on progress position.- Parameters:
fromValue
- starting float value; can be any finite floattoValue
- ending float value; can be any finite floatprogress
- how far the interpolation should go, between 0 (equal to fromValue) and 1 (equal to toValue)
-
norm
public static float norm(float rangeStart, float rangeEnd, float value) Linearly normalizes value from a range. Range must not be empty. This is the inverse oflerp(float, float, float)
.- Parameters:
rangeStart
- range start normalized to 0rangeEnd
- range end normalized to 1value
- value to normalize- Returns:
- normalized value; values outside the range are not clamped to 0 and 1
-
map
public static float map(float inRangeStart, float inRangeEnd, float outRangeStart, float outRangeEnd, float value) Linearly map a value from one range to another. Input range must not be empty. This is the same as chainingnorm(float, float, float)
from input range andlerp(float, float, float)
to output range.- Parameters:
inRangeStart
- input range startinRangeEnd
- input range endoutRangeStart
- output range startoutRangeEnd
- output range endvalue
- value to map- Returns:
- mapped value; values outside the input range are not clamped to output range
-
lerp
public static double lerp(double fromValue, double toValue, double progress) Linearly interpolates between fromValue to toValue on progress position.- Parameters:
fromValue
- starting double value; can be any finite doubletoValue
- ending double value; can be any finite doubleprogress
- how far the interpolation should go, between 0 (equal to fromValue) and 1 (equal to toValue)
-
norm
public static double norm(double rangeStart, double rangeEnd, double value) Linearly normalizes value from a range. Range must not be empty. This is the inverse oflerp(double, double, double)
.- Parameters:
rangeStart
- range start normalized to 0rangeEnd
- range end normalized to 1value
- value to normalize- Returns:
- normalized value; values outside the range are not clamped to 0 and 1
-
map
public static double map(double inRangeStart, double inRangeEnd, double outRangeStart, double outRangeEnd, double value) Linearly map a value from one range to another. Input range must not be empty. This is the same as chainingnorm(double, double, double)
from input range andlerp(double, double, double)
to output range.- Parameters:
inRangeStart
- input range startinRangeEnd
- input range endoutRangeStart
- output range startoutRangeEnd
- output range endvalue
- value to map- Returns:
- mapped value; values outside the input range are not clamped to output range
-
lerpAngle
public static float lerpAngle(float fromRadians, float toRadians, float progress) Linearly interpolates between two angles in radians. Takes into account that angles wrap atPI2
and always takes the direction with the smallest delta angle.- Parameters:
fromRadians
- start angle in radianstoRadians
- target angle in radiansprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, PI2)
-
lerpAngleDeg
public static float lerpAngleDeg(float fromDegrees, float toDegrees, float progress) Linearly interpolates between two angles in degrees. Takes into account that angles wrap at 360 degrees and always takes the direction with the smallest delta angle.- Parameters:
fromDegrees
- start angle in degreestoDegrees
- target angle in degreesprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, 360)
-
lerpAngleTurns
public static float lerpAngleTurns(float fromTurns, float toTurns, float progress) Linearly interpolates between two angles in turns. Takes into account that angles wrap at 1.0 and always takes the direction with the smallest delta angle. This version, unlike the versions for radians and degrees, avoids any modulus operation (instead callingfastFloor(float)
twice).- Parameters:
fromTurns
- start angle in turnstoTurns
- target angle in turnsprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, 1)
-
lerpAngle
public static double lerpAngle(double fromRadians, double toRadians, double progress) Linearly interpolates between two angles in radians. Takes into account that angles wrap atPI2
and always takes the direction with the smallest delta angle.- Parameters:
fromRadians
- start angle in radianstoRadians
- target angle in radiansprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, PI2)
-
lerpAngleDeg
public static double lerpAngleDeg(double fromDegrees, double toDegrees, double progress) Linearly interpolates between two angles in degrees. Takes into account that angles wrap at 360 degrees and always takes the direction with the smallest delta angle.- Parameters:
fromDegrees
- start angle in degreestoDegrees
- target angle in degreesprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, 360)
-
lerpAngleTurns
public static double lerpAngleTurns(double fromTurns, double toTurns, double progress) Linearly interpolates between two angles in turns. Takes into account that angles wrap at 1.0 and always takes the direction with the smallest delta angle. This version, unlike the versions for radians and degrees, avoids any modulus operation (instead callingfloor(double)
twice).- Parameters:
fromTurns
- start angle in turnstoTurns
- target angle in turnsprogress
- interpolation value in the range [0, 1]- Returns:
- the interpolated angle in the range [0, 1)
-
isZero
public static boolean isZero(float value) Returns true if the value is zero (using the default tolerance,FLOAT_ROUNDING_ERROR
, as outer bound).- Parameters:
value
- any float
-
isZero
public static boolean isZero(float value, float tolerance) Returns true if the value is zero, using the given tolerance.- Parameters:
value
- any floattolerance
- represent an outer bound below which the value is considered zero.
-
isZero
public static boolean isZero(double value, double tolerance) Returns true if the value is zero. A suggested tolerance is0x1p-20
, which is the same value the float overload uses for its default tolerance, or a smaller number to reduce false-positives, such as0x1p-32
.- Parameters:
value
- any doubletolerance
- represent an outer bound below which the value is considered zero.
-
zigzag
public static float zigzag(float value) Takes any float and produces a float in the -1f to 1f range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. An input of any even number should produce something very close to -1f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f or a very small fraction. This method is closely related tosway(float)
, which will smoothly curve its output to produce more values that are close to -1 or 1.- Parameters:
value
- any float- Returns:
- a float from -1f (inclusive) to 1f (inclusive)
-
sway
public static float sway(float value) Very similar toTrigTools.sinTurns(float)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently. This looks like a squished sine wave when graphed, and is essentially just interpolating between each pair of odd and even inputs using what FastNoise callsQUINTIC
interpolation. This interpolation is slightly flatter at peaks and valleys than a sine wave is.
An input of any even number should produce something very close to -1f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f or a very small fraction. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer values, this will simply return -1f or 1f.
This version of a sway method uses quintic interpolation; it uses up to the fifth power of value.- Parameters:
value
- any float other than NaN or infinite values; extremely large values can't work properly- Returns:
- a float from -1f (inclusive) to 1f (inclusive)
-
swayCubic
public static float swayCubic(float value) Very similar toTrigTools.sinTurns(float)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently. This looks like a squished sine wave when graphed, and is essentially just interpolating between each pair of odd and even inputs using what is sometimes calledHERMITE
interpolation. This interpolation is rounder at peaks and valleys than a sine wave is; it is also calledsmoothstep
in GLSL, and is called cubic here because it gets the third power of a value.
An input of any even number should produce something very close to -1f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f or a very small fraction. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer values, this will simply return -1f or 1f.- Parameters:
value
- any float other than NaN or infinite values; extremely large values can't work properly- Returns:
- a float from -1f (inclusive) to 1f (inclusive)
-
swayTight
public static float swayTight(float value) Takes any float and produces a float in the 0f to 1f range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle.
An input of any even number should produce something very close to 0f, any odd number should produce something very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0.5f. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer values, this will simply return 0f or 1f. This version is called "Tight" because its range is tighter thansway(float)
.
This version of a sway method uses quintic interpolation; it uses up to the fifth power of value.- Parameters:
value
- any float other than NaN or infinite values; extremely large values can't work properly- Returns:
- a float from 0f (inclusive) to 1f (inclusive)
-
zigzag
public static double zigzag(double value) Takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. An input of any even number should produce something very close to -1.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 or a very small fraction. This method is closely related tosway(double)
, which will smoothly curve its output to produce more values that are close to -1 or 1.- Parameters:
value
- any double- Returns:
- a double from -1.0 (inclusive) to 1.0 (inclusive)
-
sway
public static double sway(double value) Very similar toTrigTools.sinTurns(double)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently. This looks like a squished sine wave when graphed, and is essentially just interpolating between each pair of odd and even inputs using what FastNoise callsQUINTIC
interpolation. This interpolation is slightly flatter at peaks and valleys than a sine wave is.
An input of any even number should produce something very close to -1.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 or a very small fraction. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer values, this will simply return -1.0 or 1.0.
This version of a sway method uses quintic interpolation; it uses up to the fifth power of value.- Parameters:
value
- any double other than NaN or infinite values; extremely large values can't work properly- Returns:
- a double from -1.0 (inclusive) to 1.0 (inclusive)
-
swayCubic
public static double swayCubic(double value) Very similar toTrigTools.sinTurns(double)
with half frequency, orMath.sin(double)
withMath.PI
frequency, but optimized (and shaped) a little differently. This looks like a squished sine wave when graphed, and is essentially just interpolating between each pair of odd and even inputs using what is sometimes calledHERMITE
interpolation. This interpolation is rounder at peaks and valleys than a sine wave is; it is also calledsmoothstep
in GLSL, and is called cubic here because it gets the third power of a value.
An input of any even number should produce something very close to -1.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 or a very small fraction. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer values, this will simply return -1.0 or 1.0.- Parameters:
value
- any double other than NaN or infinite values; extremely large values can't work properly- Returns:
- a double from -1.0 (inclusive) to 1.0 (inclusive)
-
swayTight
public static double swayTight(double value) Takes any double and produces a double in the 0.0 to 1.0 range, with a graph of input to output that looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle.
An input of any even number should produce something very close to 0.0, any odd number should produce something very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.5. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer values, this will simply return 0.0 or 1.0. This version is called "Tight" because its range is tighter thansway(double)
.
This version of a sway method uses quintic interpolation; it uses up to the fifth power of value.- Parameters:
value
- any double other than NaN or infinite values; extremely large values can't work properly- Returns:
- a double from 0.0 (inclusive) to 1.0 (inclusive)
-
boundedInt
public static int boundedInt(long state, int bound) Given a state that is typically random-seeming, this produces an int within a bounded range that is similarly random-seeming.- Parameters:
state
- can be a long or an int; typically produced by a random- or hash-like processbound
- the outer exclusive bound, as an int- Returns:
- an int between 0 (inclusive) and bound (exclusive)
-
boundedLong
public static long boundedLong(long state, long innerBound, long outerBound) Given a state that is typically random-seeming, this produces a long within a bounded range that is similarly random-seeming.- Parameters:
state
- must be a long; typically produced by a random- or hash-like processinnerBound
- the inner exclusive bound, as a longouterBound
- the outer exclusive bound, as a long- Returns:
- a long between innerBound (inclusive) and outerBound (exclusive)
-