Class MathUtils


  • public final class MathUtils
    extends java.lang.Object
    Utility and fast math functions.

    Thanks to Riven on JavaGaming.org for the basis of sin/cos/floor/ceil.

    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static float acos​(float a)
      Returns acos in radians; less accurate than Math.acos but may be faster.
      static float acosDeg​(float a)
      Returns arccosine in degrees.
      static float asin​(float a)
      Returns asin in radians; less accurate than Math.asin but may be faster.
      static float asinDeg​(float a)
      Returns arcsine in degrees.
      static float atan​(float i)
      Arc tangent approximation with very low error, using an algorithm from the 1955 research study "Approximations for Digital Computers," by RAND Corporation (this is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise).
      static float atan2​(float y, float x)
      Close approximation of the frequently-used trigonometric method atan2.
      static float atan2Deg​(float y, float x)
      Close approximation of the frequently-used trigonometric method atan2, using positive or negative degrees.
      static float atan2Deg360​(float y, float x)
      Close approximation of the frequently-used trigonometric method atan2, using non-negative degrees only.
      static float atanDeg​(float i)
      Arc tangent approximation returning a value measured in positive or negative degrees, using an algorithm from the 1955 research study "Approximations for Digital Computers," by RAND Corporation (this is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise).
      static float atanUnchecked​(double i)
      A variant on atan(float) that does not tolerate infinite inputs for speed reasons.
      static double atanUncheckedDeg​(double i)
      A variant on atanDeg(float) that does not tolerate infinite inputs for speed reasons.
      static int ceil​(float value)
      Returns the smallest integer 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)  
      static float clamp​(float value, float min, float max)  
      static int clamp​(int value, int min, int max)  
      static long clamp​(long value, long min, long max)  
      static short clamp​(short value, short min, short max)  
      static float cos​(float radians)
      Returns the cosine in radians from a lookup table.
      static float cosDeg​(float degrees)
      Returns the cosine in degrees from a lookup table.
      static int floor​(float value)
      Returns the largest integer less than or equal to the specified float.
      static int floorPositive​(float value)
      Returns the largest integer less than or equal to the specified float.
      static boolean isEqual​(float a, float b)
      Returns true if a is nearly equal to b.
      static boolean isEqual​(float a, float b, float tolerance)
      Returns true if a is nearly equal to b.
      static boolean isPowerOfTwo​(int value)  
      static boolean isZero​(float value)
      Returns true if the value is zero (using the default tolerance as upper bound)
      static boolean isZero​(float value, float tolerance)
      Returns true if the value is zero.
      static float lerp​(float fromValue, float toValue, float progress)
      Linearly interpolates between fromValue to toValue on progress position.
      static float lerpAngle​(float fromRadians, float toRadians, float progress)
      Linearly interpolates between two angles in radians.
      static float lerpAngleDeg​(float fromDegrees, float toDegrees, float progress)
      Linearly interpolates between two angles in degrees.
      static float log​(float a, float value)  
      static float log2​(float value)  
      static float map​(float inRangeStart, float inRangeEnd, float outRangeStart, float outRangeEnd, float value)
      Linearly map a value from one range to another.
      static int nextPowerOfTwo​(int value)
      Returns the next power of two.
      static float norm​(float rangeStart, float rangeEnd, float value)
      Linearly normalizes value from a range.
      static float random()
      Returns random number between 0.0 (inclusive) and 1.0 (exclusive).
      static float random​(float range)
      Returns a random number between 0 (inclusive) and the specified value (exclusive).
      static float random​(float start, float end)
      Returns a random number between start (inclusive) and end (exclusive).
      static int random​(int range)
      Returns a random number between 0 (inclusive) and the specified value (inclusive).
      static int random​(int start, int end)
      Returns a random number between start (inclusive) and end (inclusive).
      static long random​(long range)
      Returns a random number between 0 (inclusive) and the specified value (inclusive).
      static long random​(long start, long end)
      Returns a random number between start (inclusive) and end (inclusive).
      static boolean randomBoolean()
      Returns a random boolean value.
      static boolean randomBoolean​(float chance)
      Returns true if a random value between 0 and 1 is less than the specified value.
      static int randomSign()
      Returns -1 or 1, randomly.
      static float randomTriangular()
      Returns a triangularly distributed random number between -1.0 (exclusive) and 1.0 (exclusive), where values around zero are more likely.
      static float randomTriangular​(float max)
      Returns a triangularly distributed random number between -max (exclusive) and max (exclusive), where values around zero are more likely.
      static float randomTriangular​(float min, float max)
      Returns a triangularly distributed random number between min (inclusive) and max (exclusive), where the mode argument defaults to the midpoint between the bounds, giving a symmetric distribution.
      static float randomTriangular​(float min, float max, float mode)
      Returns a triangularly distributed random number between min (inclusive) and max (exclusive), where values around mode are more likely.
      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 float sin​(float radians)
      Returns the sine in radians from a lookup table.
      static float sinDeg​(float degrees)
      Returns the sine in degrees from a lookup table.
      static float tan​(float radians)
      Returns the tangent given an input in radians, using a Padé approximant.
      static float tanDeg​(float degrees)
      Returns the tangent given an input in degrees, using a Padé approximant.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • sin

        public static float sin​(float radians)
        Returns the sine in radians from a lookup table. For optimal precision, use radians between -PI2 and PI2 (both inclusive).
      • cos

        public static float cos​(float radians)
        Returns the cosine in radians from a lookup table. For optimal precision, use radians between -PI2 and PI2 (both inclusive).
      • sinDeg

        public static float sinDeg​(float degrees)
        Returns the sine in degrees from a lookup table. For optimal precision, use degrees between -360 and 360 (both inclusive).
      • cosDeg

        public static float cosDeg​(float degrees)
        Returns the cosine in degrees from a lookup table. For optimal precision, use degrees between -360 and 360 (both inclusive).
      • tan

        public static float tan​(float radians)
        Returns the tangent given an input in radians, using a Padé approximant.
        Padé approximants tend to be most accurate when they aren't producing results of extreme magnitude; in the tan() function, those results occur on and near odd multiples of PI/2, and this method is least accurate when given inputs near those multiples.
        For inputs between -1.57 to 1.57 (just inside half-pi), separated by 0x1p-20f, absolute error is 0.00890192, relative error is 0.00000090, and the maximum error is 17.98901367 when given 1.56999838. The maximum error might seem concerning, but it's the difference between the correct 1253.22167969 and the 1235.23266602 this returns, so for many purposes the difference won't be noticeable.
        For inputs between -1.55 to 1.55 (getting less close to half-pi), separated by 0x1p-20f, absolute error is 0.00023368, relative error is -0.00000009, and the maximum error is 0.02355957 when given -1.54996467. The maximum error is the difference between the correct -47.99691010 and the -47.97335052 this returns.
        While you don't have to use a dedicated method for tan(), and you can use sin(x)/cos(x), approximating tan() in that way is very susceptible to error building up from any of sin(), cos() or the division. Where this tan() has a maximum error in the -1.55 to 1.55 range of 0.02355957, that simpler division technique on the same range has a maximum error of 1.25724030 (about 50 times worse), as well as larger absolute and relative errors. Casting the double result of Math.tan(double) to float will get the highest precision, but can be anywhere from 2.5x to nearly 4x slower than this, depending on JVM.
        Based on this Stack Exchange answer by Soonts.
        Parameters:
        radians - a float angle in radians, where 0 to PI2 is one rotation
        Returns:
        a float approximation of tan()
      • tanDeg

        public static float tanDeg​(float degrees)
        Returns the tangent given an input in degrees, using a Padé approximant. Based on this Stack Exchange answer.
        Parameters:
        degrees - an angle in degrees, where 0 to 360 is one rotation
        Returns:
        a float approximation of tan()
      • atanUnchecked

        public static float atanUnchecked​(double i)
        A variant on atan(float) that does not tolerate infinite inputs for speed reasons. This can be given a double parameter, but is otherwise the same as atan(float), and returns a float like that method. It uses the same approximation, from sheet 11 of "Approximations for Digital Computers." This is mostly meant to be used inside atan2(float, float), but it may be a tiny bit faster than atan(float) in other code.
        Parameters:
        i - any finite double or float, but more commonly a float
        Returns:
        an output from the inverse tangent function, from -HALF_PI to HALF_PI inclusive
      • atan2

        public static float atan2​(float y,
                                  float x)
        Close approximation of the frequently-used trigonometric method atan2. Average error is 1.057E-6 radians; maximum error is 1.922E-6. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in radians. It is about 4 times faster than Math.atan2(double, double) (roughly 15 ns instead of roughly 60 ns for Math, on Java 8 HotSpot).
        Credit for this goes to the 1955 research study "Approximations for Digital Computers," by RAND Corporation. This is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise. The algorithms on sheets 8-10 are faster, but only by a very small degree, and are considerably less precise. That study provides an atan(float) method, and that cleanly translates to atan2().
        Parameters:
        y - y-component of the point to find the angle towards; note the parameter order is unusual by convention
        x - x-component of the point to find the angle towards; note the parameter order is unusual by convention
        Returns:
        the angle to the given point, in radians as a float; ranges from -PI to PI
      • atanUncheckedDeg

        public static double atanUncheckedDeg​(double i)
        A variant on atanDeg(float) that does not tolerate infinite inputs for speed reasons. This can be given a double parameter, but is otherwise the same as atanDeg(float), and returns a float like that method. It uses the same approximation, from sheet 11 of "Approximations for Digital Computers." This is mostly meant to be used inside atan2(float, float), but it may be a tiny bit faster than atanDeg(float) in other code.
        Parameters:
        i - any finite double or float, but more commonly a float
        Returns:
        an output from the inverse tangent function in degrees, from -90 to 90 inclusive
      • atan2Deg

        public static float atan2Deg​(float y,
                                     float x)
        Close approximation of the frequently-used trigonometric method atan2, using positive or negative degrees. Average absolute error is 0.00006037 degrees; relative error is 0 degrees, maximum error is 0.00010396 degrees. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees.
        Credit for this goes to the 1955 research study "Approximations for Digital Computers," by RAND Corporation. This is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise. The algorithms on sheets 8-10 are faster, but only by a very small degree, and are considerably less precise. That study provides an atan(float) method, and that cleanly translates to atan2().
        Parameters:
        y - y-component of the point to find the angle towards; note the parameter order is unusual by convention
        x - x-component of the point to find the angle towards; note the parameter order is unusual by convention
        Returns:
        the angle to the given point, in degrees as a float; ranges from -180 to 180
      • atan2Deg360

        public static float atan2Deg360​(float y,
                                        float x)
        Close approximation of the frequently-used trigonometric method atan2, using non-negative degrees only. Average absolute error is 0.00006045 degrees; relative error is 0 degrees; maximum error is 0.00011178 degrees. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees.
        This can be useful when a negative result from atan() would require extra work to handle.
        Credit for this goes to the 1955 research study "Approximations for Digital Computers," by RAND Corporation. This is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise. The algorithms on sheets 8-10 are faster, but only by a very small degree, and are considerably less precise. That study provides an atan(float) method, and that cleanly translates to atan2Deg360().
        Parameters:
        y - y-component of the point to find the angle towards; note the parameter order is unusual by convention
        x - x-component of the point to find the angle towards; note the parameter order is unusual by convention
        Returns:
        the angle to the given point, in degrees as a float; ranges from 0 to 360
      • acos

        public static float acos​(float a)
        Returns acos in radians; less accurate than Math.acos but may be faster. Average error of 0.00002845 radians (0.0016300649 degrees), largest error of 0.000067548 radians (0.0038702153 degrees). This implementation does not return NaN if given an out-of-range input (Math.acos does return NaN), unless the input is NaN.
        Parameters:
        a - acos is defined only when a is between -1f and 1f, inclusive
        Returns:
        between 0 and PI when a is in the defined range
      • asin

        public static float asin​(float a)
        Returns asin in radians; less accurate than Math.asin but may be faster. Average error of 0.000028447 radians (0.0016298931 degrees), largest error of 0.000067592 radians (0.0038727364 degrees). This implementation does not return NaN if given an out-of-range input (Math.asin does return NaN), unless the input is NaN.
        Parameters:
        a - asin is defined only when a is between -1f and 1f, inclusive
        Returns:
        between -HALF_PI and HALF_PI when a is in the defined range
      • atan

        public static float atan​(float i)
        Arc tangent approximation with very low error, using an algorithm from the 1955 research study "Approximations for Digital Computers," by RAND Corporation (this is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise). This method is usually about 4x faster than Math.atan(double), but is somewhat less precise than Math's implementation. For finite inputs only, you may get a tiny speedup by using atanUnchecked(double), but this method will be correct enough for infinite inputs, and atanUnchecked() will not be.
        Parameters:
        i - an input to the inverse tangent function; any float is accepted
        Returns:
        an output from the inverse tangent function, from -HALF_PI to HALF_PI inclusive
        See Also:
        If you know the input will be finite, you can use atanUnchecked() instead.
      • asinDeg

        public static float asinDeg​(float a)
        Returns arcsine in degrees. This implementation does not return NaN if given an out-of-range input (Math.asin does return NaN), unless the input is NaN.
        Parameters:
        a - asin is defined only when a is between -1f and 1f, inclusive
        Returns:
        between -90 and 90 when a is in the defined range
      • acosDeg

        public static float acosDeg​(float a)
        Returns arccosine in degrees. This implementation does not return NaN if given an out-of-range input (Math.acos does return NaN), unless the input is NaN.
        Parameters:
        a - acos is defined only when a is between -1f and 1f, inclusive
        Returns:
        between 0 and 180 when a is in the defined range
      • atanDeg

        public static float atanDeg​(float i)
        Arc tangent approximation returning a value measured in positive or negative degrees, using an algorithm from the 1955 research study "Approximations for Digital Computers," by RAND Corporation (this is sheet 11's algorithm, which is the fourth-fastest and fourth-least precise). For finite inputs only, you may get a tiny speedup by using atanUncheckedDeg(double), but this method will be correct enough for infinite inputs, and atanUnchecked() will not be.
        Parameters:
        i - an input to the inverse tangent function; any float is accepted
        Returns:
        an output from the inverse tangent function in degrees, from -90 to 90 inclusive
        See Also:
        If you know the input will be finite, you can use atanUncheckedDeg() instead.
      • random

        public static int random​(int range)
        Returns a random number between 0 (inclusive) and the specified value (inclusive).
      • random

        public static int random​(int start,
                                 int end)
        Returns a random number between start (inclusive) and end (inclusive).
      • random

        public static long random​(long range)
        Returns a random number between 0 (inclusive) and the specified value (inclusive).
      • random

        public static long random​(long start,
                                  long end)
        Returns a random number between start (inclusive) and end (inclusive).
      • randomBoolean

        public static boolean randomBoolean()
        Returns a random boolean value.
      • randomBoolean

        public static boolean randomBoolean​(float chance)
        Returns true if a random value between 0 and 1 is less than the specified value.
      • random

        public static float random()
        Returns random number between 0.0 (inclusive) and 1.0 (exclusive).
      • random

        public static float random​(float range)
        Returns a random number between 0 (inclusive) and the specified value (exclusive).
      • random

        public static float random​(float start,
                                   float end)
        Returns a random number between start (inclusive) and end (exclusive).
      • randomSign

        public static int randomSign()
        Returns -1 or 1, randomly.
      • randomTriangular

        public static float randomTriangular()
        Returns a triangularly distributed random number between -1.0 (exclusive) and 1.0 (exclusive), where values around zero are more likely.

        This is an optimized version of randomTriangular(-1, 1, 0)

      • randomTriangular

        public static float randomTriangular​(float max)
        Returns a triangularly distributed random number between -max (exclusive) and max (exclusive), where values around zero are more likely.

        This is an optimized version of randomTriangular(-max, max, 0)

        Parameters:
        max - the upper limit
      • randomTriangular

        public static float randomTriangular​(float min,
                                             float max)
        Returns a triangularly distributed random number between min (inclusive) and max (exclusive), where the mode argument defaults to the midpoint between the bounds, giving a symmetric distribution.

        This method is equivalent of randomTriangular(min, max, (min + max) * 0.5f)

        Parameters:
        min - the lower limit
        max - the upper limit
      • randomTriangular

        public static float randomTriangular​(float min,
                                             float max,
                                             float mode)
        Returns a triangularly distributed random number between min (inclusive) and max (exclusive), where values around mode are more likely.
        Parameters:
        min - the lower limit
        max - the upper limit
        mode - the point around which the values are more likely
      • nextPowerOfTwo

        public static int nextPowerOfTwo​(int value)
        Returns the next power of two. Returns the specified value if the value is already a power of two.
      • isPowerOfTwo

        public static boolean isPowerOfTwo​(int value)
      • clamp

        public static short clamp​(short value,
                                  short min,
                                  short max)
      • clamp

        public static int clamp​(int value,
                                int min,
                                int max)
      • clamp

        public static long clamp​(long value,
                                 long min,
                                 long max)
      • clamp

        public static float clamp​(float value,
                                  float min,
                                  float max)
      • clamp

        public static double clamp​(double value,
                                   double min,
                                   double max)
      • lerp

        public static float lerp​(float fromValue,
                                 float toValue,
                                 float progress)
        Linearly interpolates between fromValue to toValue on progress position.
      • 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 of lerp(float, float, float).
        Parameters:
        rangeStart - Range start normalized to 0
        rangeEnd - Range end normalized to 1
        value - Value to normalize
        Returns:
        Normalized value. Values outside of 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 chaining norm(float, float, float) from input range and lerp(float, float, float) to output range.
        Parameters:
        inRangeStart - Input range start
        inRangeEnd - Input range end
        outRangeStart - Output range start
        outRangeEnd - Output range end
        value - Value to map
        Returns:
        Mapped value. Values outside of 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 at two pi and always takes the direction with the smallest delta angle.
        Parameters:
        fromRadians - start angle in radians
        toRadians - target angle in radians
        progress - 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 degrees
        toDegrees - target angle in degrees
        progress - interpolation value in the range [0, 1]
        Returns:
        the interpolated angle in the range [0, 360[
      • floor

        public static int floor​(float value)
        Returns the largest integer less than or equal to the specified float. This method will only properly floor floats from -(2^14) to (Float.MAX_VALUE - 2^14).
      • floorPositive

        public static int floorPositive​(float value)
        Returns the largest integer 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.
      • ceil

        public static int ceil​(float value)
        Returns the smallest integer greater than or equal to the specified float. This method will only properly ceil floats 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.
      • 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).
      • 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.
      • isZero

        public static boolean isZero​(float value)
        Returns true if the value is zero (using the default tolerance as upper bound)
      • isZero

        public static boolean isZero​(float value,
                                     float tolerance)
        Returns true if the value is zero.
        Parameters:
        tolerance - represent an upper bound below which the value is considered zero.
      • isEqual

        public static boolean isEqual​(float a,
                                      float b)
        Returns true if a is nearly equal to b. The function uses the default floating error tolerance.
        Parameters:
        a - the first value.
        b - the second value.
      • isEqual

        public static boolean isEqual​(float a,
                                      float b,
                                      float tolerance)
        Returns true if a is nearly equal to b.
        Parameters:
        a - the first value.
        b - the second value.
        tolerance - represent an upper bound below which the two values are considered equal.
      • log

        public static float log​(float a,
                                float value)
        Returns:
        the logarithm of value with base a
      • log2

        public static float log2​(float value)
        Returns:
        the logarithm of value with base 2