Class TrigTools

java.lang.Object
com.github.tommyettinger.digital.TrigTools

public final class TrigTools extends Object
Various trigonometric approximations, using a lookup table for sin() and cos(), a non-tabular approximation for sinSmooth() and cosSmooth(), a Padé approximant for tan(), and Taylor series for the inverses of sin(), cos(), and tan(). This supplies variants for radians, degrees, and turns. This also has an atan2() approximation defined with output in radians, degrees, and turns. The lookup-table-based sin() and cos() can be extraordinarily fast if the 64KB table can stay in a processor cache, while the "smooth" approximations may have higher quality but perform less quickly compared to an in-cache lookup table.
This is primarily derived from libGDX's MathUtils class. The main new functionalities are the variants that take or return measurements in turns, the now-available SIN_TABLE and SIN_TABLE_D, and double variants in general. Using the sin table directly has other uses mentioned in its docs (in particular, uniform random unit vectors). Because using a lookup table for sine and cosine has very small "jumps" between what it returns for smoothly increasing inputs, it may be unsuitable for some usage, such as calculating tan() or some statistical code. TrigTools provides sinSmooth(), cosSmooth(), and degree/turn variants of those for when the precision should be high but it is most important to have a smoothly-curving graph of returns. A different smooth approximation is used for tan().
MathUtils had its sin and cos methods created by Riven on JavaGaming.org . The asin(), acos(), and atan() methods all use Taylor series approximations from the 1955 research study "Approximations for Digital Computers," by RAND Corporation; though one might think such code would be obsolete over 60 years later, the approximations from that study seem to have higher accuracy and speed than most attempts in later decades, often those aimed at DSP usage. Even older is the basis for sinSmooth() and cosSmooth(); the versions here are updated to be more precise, but are closely related to a 7th-century sine approximation by Bhaskara I. The update was given in this Stack Exchange answer by WimC. Also from Stack Exchange, this Stack Exchange answer by Soonts provided the tan() approximation used here.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final float
    Multiply by this to convert from degrees to radians.
    static final double
    Multiply by this to convert from degrees to radians.
    static final float
    PI divided by 2f; the same as HALF_PI.
    static final double
    Math.PI divided by 2.0; the same as HALF_PI_D.
    static final float
    PI divided by 2f; the same as ETA.
    static final double
    Math.PI divided by 2.0; the same as ETA_D.
    static final float
    The float value that is closer than any other to pi, the ratio of the circumference of a circle to its diameter.
    static final double
    The double value that is closer than any other to pi, the ratio of the circumference of a circle to its diameter.
    static final float
    1.0f divided by PI.
    static final double
    1.0 divided by PI.
    static final float
    2f times PI; the same as TAU.
    static final double
    2.0 times Math.PI; the same as TAU_D.
    static final float
    PI divided by 4f.
    static final double
    Math.PI divided by 4.0.
    static final float
    Multiply by this to convert from radians to degrees.
    static final double
    Multiply by this to convert from radians to degrees.
    static final float[]
    A precalculated table of 16384 floats, corresponding to the y-value of points on the unit circle, ordered by increasing angle.
    static final double[]
    A precalculated table of 16384 doubles, corresponding to the y-value of points on the unit circle, ordered by increasing angle.
    static final int
    If you add this to an index used in SIN_TABLE, you get the result of the cosine instead of the sine.
    static final int
    The bitmask that can be used to confine any int to wrap within TABLE_SIZE.
    static final int
    The size of SIN_TABLE, available separately from the table's length for convenience.
    static final float
    2f times PI; the same as PI2.
    static final double
    2.0 times Math.PI; the same as PI2_D.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    acos(double a)
    Returns arccosine in radians; less accurate than Math.acos but may be faster.
    static float
    acos(float a)
    Returns arccosine in radians; less accurate than Math.acos but may be faster.
    static double
    acosDeg(double a)
    Returns arccosine in degrees.
    static float
    acosDeg(float a)
    Returns arccosine in degrees.
    static double
    acosTurns(double a)
    Returns arccosine in turns.
    static float
    acosTurns(float a)
    Returns arccosine in turns.
    static double
    asin(double a)
    Returns arcsine in radians; less accurate than Math.asin but may be faster.
    static float
    asin(float a)
    Returns arcsine in radians; less accurate than Math.asin but may be faster.
    static double
    asinDeg(double a)
    Returns arcsine in degrees.
    static float
    asinDeg(float a)
    Returns arcsine in degrees.
    static double
    asinTurns(double a)
    Returns arcsine in turns.
    static float
    asinTurns(float a)
    Returns arcsine in turns.
    static double
    atan(double 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
    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 double
    atan2(double y, double x)
    Close approximation of the frequently-used trigonometric method atan2, using radians.
    static float
    atan2(float y, float x)
    Close approximation of the frequently-used trigonometric method atan2, using radians.
    static double
    atan2Deg(double y, double x)
    Close approximation of the frequently-used trigonometric method atan2, using positive or negative degrees.
    static float
    atan2Deg(float y, float x)
    Close approximation of the frequently-used trigonometric method atan2, using positive or negative degrees.
    static double
    atan2Deg360(double y, double x)
    Close approximation of the frequently-used trigonometric method atan2, using non-negative degrees only.
    static float
    atan2Deg360(float y, float x)
    Close approximation of the frequently-used trigonometric method atan2, using non-negative degrees only.
    static double
    atan2Turns(double y, double x)
    Close approximation of the frequently-used trigonometric method atan2, using non-negative turns only.
    static float
    atan2Turns(float y, float x)
    Close approximation of the frequently-used trigonometric method atan2, using non-negative turns only.
    static double
    atanDeg(double 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
    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 double
    atanTurns(double 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
    atanTurns(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 double
    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 double
    A variant on atanTurns(float) that does not tolerate infinite inputs for speed reasons.
    static double
    cos(double radians)
    Returns the cosine in radians from a lookup table.
    static float
    cos(float radians)
    Returns the cosine in radians from a lookup table.
    static double
    cosDeg(double degrees)
    Returns the cosine in degrees from a lookup table.
    static float
    cosDeg(float degrees)
    Returns the cosine in degrees from a lookup table.
    static double
    cosSmooth(double radians)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    cosSmooth(float radians)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    cosSmoothDeg(double degrees)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    cosSmoothDeg(float degrees)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    cosSmoothTurns(double turns)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    cosSmoothTurns(float turns)
    A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    cosTurns(double turns)
    Returns the cosine in turns from a lookup table.
    static float
    cosTurns(float turns)
    Returns the cosine in turns from a lookup table.
    static double
    sin(double radians)
    Returns the sine in radians from a lookup table.
    static float
    sin(float radians)
    Returns the sine in radians from a lookup table.
    static double
    sinDeg(double degrees)
    Returns the sine in degrees from a lookup table.
    static float
    sinDeg(float degrees)
    Returns the sine in degrees from a lookup table.
    static double
    sinSmooth(double radians)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    sinSmooth(float radians)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    sinSmoothDeg(double degrees)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    sinSmoothDeg(float degrees)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    sinSmoothTurns(double turns)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static float
    sinSmoothTurns(float turns)
    A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century.
    static double
    sinTurns(double turns)
    Returns the sine in turns from a lookup table.
    static float
    sinTurns(float turns)
    Returns the sine in turns from a lookup table.
    static double
    tan(double radians)
    Returns the tangent in radians, using a Padé approximant.
    static float
    tan(float radians)
    Returns the tangent in radians, using a Padé approximant.
    static double
    tanDeg(double degrees)
    Returns the tangent in degrees, using a Padé approximant.
    static float
    tanDeg(float degrees)
    Returns the tangent in degrees, using a Padé approximant.
    static double
    tanTurns(double turns)
    Returns the tangent in turns, using a Padé approximant.
    static float
    tanTurns(float turns)
    Returns the tangent in turns, using a Padé approximant.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • PI

      public static final float PI
      The float value that is closer than any other to pi, the ratio of the circumference of a circle to its diameter.
      See Also:
    • PI_D

      public static final double PI_D
      The double value that is closer than any other to pi, the ratio of the circumference of a circle to its diameter.
      See Also:
    • PI_INVERSE

      public static final float PI_INVERSE
      1.0f divided by PI.
      See Also:
    • PI2

      public static final float PI2
      2f times PI; the same as TAU.
      See Also:
    • TAU

      public static final float TAU
      2f times PI; the same as PI2.
      See Also:
    • HALF_PI

      public static final float HALF_PI
      PI divided by 2f; the same as ETA.
      See Also:
    • ETA

      public static final float ETA
      PI divided by 2f; the same as HALF_PI.
      See Also:
    • PI_INVERSE_D

      public static final double PI_INVERSE_D
      1.0 divided by PI.
      See Also:
    • PI2_D

      public static final double PI2_D
      2.0 times Math.PI; the same as TAU_D.
      See Also:
    • TAU_D

      public static final double TAU_D
      2.0 times Math.PI; the same as PI2_D.
      See Also:
    • HALF_PI_D

      public static final double HALF_PI_D
      Math.PI divided by 2.0; the same as ETA_D.
      See Also:
    • ETA_D

      public static final double ETA_D
      Math.PI divided by 2.0; the same as HALF_PI_D.
      See Also:
    • QUARTER_PI

      public static final float QUARTER_PI
      PI divided by 4f.
      See Also:
    • QUARTER_PI_D

      public static final double QUARTER_PI_D
      Math.PI divided by 4.0.
      See Also:
    • TABLE_SIZE

      public static final int TABLE_SIZE
      The size of SIN_TABLE, available separately from the table's length for convenience.
      See Also:
    • SIN_TO_COS

      public static final int SIN_TO_COS
      If you add this to an index used in SIN_TABLE, you get the result of the cosine instead of the sine.
      See Also:
    • TABLE_MASK

      public static final int TABLE_MASK
      The bitmask that can be used to confine any int to wrap within TABLE_SIZE. Any accesses to SIN_TABLE with an index that could be out of bounds should probably be wrapped using this, as with SIN_TABLE[index & TABLE_MASK].
      See Also:
    • radiansToDegrees

      public static final float radiansToDegrees
      Multiply by this to convert from radians to degrees.
      See Also:
    • degreesToRadians

      public static final float degreesToRadians
      Multiply by this to convert from degrees to radians.
      See Also:
    • radiansToDegreesD

      public static final double radiansToDegreesD
      Multiply by this to convert from radians to degrees.
      See Also:
    • degreesToRadiansD

      public static final double degreesToRadiansD
      Multiply by this to convert from degrees to radians.
      See Also:
    • SIN_TABLE

      public static final float[] SIN_TABLE
      A precalculated table of 16384 floats, corresponding to the y-value of points on the unit circle, ordered by increasing angle. This should not be mutated, but it can be accessed directly for things like getting random unit vectors, or implementing the "sincos" method (which assigns sin() to one item and cos() to another).
      A quick way to get a random unit vector is to get a random 14-bit number, as with int angle = random.nextInt() >>> 18;, look up angle in this table to get y, then look up (angle + TrigTools.SIN_TO_COS) & TrigTools.TABLE_MASK (or (angle + 4096) & 16383) to get x.
    • SIN_TABLE_D

      public static final double[] SIN_TABLE_D
      A precalculated table of 16384 doubles, corresponding to the y-value of points on the unit circle, ordered by increasing angle. This should not be mutated, but it can be accessed directly for things like getting random unit vectors, or implementing the "sincos" method (which assigns sin() to one item and cos() to another).
      A quick way to get a random unit vector is to get a random 14-bit number, as with int angle = random.nextInt() >>> 18;, look up angle in this table to get y, then look up (angle + TrigTools.SIN_TO_COS) & TrigTools.TABLE_MASK (or (angle + 4096) & 16383) to get x.
  • Method Details

    • 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).
      Parameters:
      radians - an angle in radians, where 0 to PI2 is one rotation
    • 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).
      Parameters:
      radians - an angle in radians, where 0 to PI2 is one rotation
    • tan

      public static float tan(float radians)
      Returns the tangent 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 this 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, the 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()
    • 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).
      Parameters:
      degrees - an angle in degrees, where 0 to 360 is one rotation
    • 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).
      Parameters:
      degrees - an angle in degrees, where 0 to 360 is one rotation
    • tanDeg

      public static float tanDeg(float degrees)
      Returns the tangent 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()
    • sinTurns

      public static float sinTurns(float turns)
      Returns the sine in turns from a lookup table. For optimal precision, use turns between -1 and 1 (both inclusive).
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
    • cosTurns

      public static float cosTurns(float turns)
      Returns the cosine in turns from a lookup table. For optimal precision, use turns between -1 and 1 (both inclusive).
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
    • tanTurns

      public static float tanTurns(float turns)
      Returns the tangent in turns, using a Padé approximant. Based on this Stack Exchange answer.
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
      Returns:
      a float approximation of tan()
    • sin

      public static double sin(double radians)
      Returns the sine in radians from a lookup table. For optimal precision, use radians between -PI2 and PI2 (both inclusive).
      Parameters:
      radians - an angle in radians, where 0 to PI2_D is one rotation
    • cos

      public static double cos(double radians)
      Returns the cosine in radians from a lookup table. For optimal precision, use radians between -PI2 and PI2 (both inclusive).
      Parameters:
      radians - an angle in radians, where 0 to PI2_D is one rotation
    • tan

      public static double tan(double radians)
      Returns the tangent in radians, using a Padé approximant. Based on this Stack Exchange answer.
      Parameters:
      radians - a double angle in radians, where 0 to PI2 is one rotation
      Returns:
      a double approximation of tan()
    • sinDeg

      public static double sinDeg(double degrees)
      Returns the sine in degrees from a lookup table. For optimal precision, use degrees between -360 and 360 (both inclusive).
      Parameters:
      degrees - an angle in degrees, where 0 to 360 is one rotation
    • cosDeg

      public static double cosDeg(double degrees)
      Returns the cosine in degrees from a lookup table. For optimal precision, use degrees between -360 and 360 (both inclusive).
      Parameters:
      degrees - an angle in degrees, where 0 to 360 is one rotation
    • tanDeg

      public static double tanDeg(double degrees)
      Returns the tangent 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 double approximation of tan()
    • sinTurns

      public static double sinTurns(double turns)
      Returns the sine in turns from a lookup table. For optimal precision, use turns between -1 and 1 (both inclusive).
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
    • cosTurns

      public static double cosTurns(double turns)
      Returns the cosine in turns from a lookup table. For optimal precision, use turns between -1 and 1 (both inclusive).
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
    • tanTurns

      public static double tanTurns(double turns)
      Returns the tangent in turns, using a Padé approximant. Based on this Stack Exchange answer.
      Parameters:
      turns - an angle in turns, where 0 to 1 is one rotation
      Returns:
      a double approximation of tan()
    • sinSmooth

      public static float sinSmooth(float radians)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in radians, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sin(); in particular, only 16384 outputs are possible from sin(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sin() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      radians - an angle in radians; most precise between -PI2 and PI2
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmooth

      public static float cosSmooth(float radians)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in radians, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cos(); in particular, only 16384 outputs are possible from cos(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cos() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      radians - an angle in radians; most precise between -PI2 and PI2
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • sinSmooth

      public static double sinSmooth(double radians)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in radians, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sin(); in particular, only 16384 outputs are possible from sin(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sin() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      radians - an angle in radians; most precise between -PI2 and PI2
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmooth

      public static double cosSmooth(double radians)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in radians, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cos(); in particular, only 16384 outputs are possible from cos(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cos() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      radians - an angle in radians; most precise between -PI2 and PI2
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • sinSmoothDeg

      public static float sinSmoothDeg(float degrees)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in degrees, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sinDeg(); in particular, only 16384 outputs are possible from sinDeg(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sinDeg() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      degrees - an angle in degrees; most precise between -360 and 360
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmoothDeg

      public static float cosSmoothDeg(float degrees)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in degrees, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cosDeg(); in particular, only 16384 outputs are possible from cosDeg(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cosDeg() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      degrees - an angle in degrees; most precise between -360 and 360
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • sinSmoothDeg

      public static double sinSmoothDeg(double degrees)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in degrees, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sinDeg(); in particular, only 16384 outputs are possible from sinDeg(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sinDeg() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      degrees - an angle in degrees; most precise between -360 and 360
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmoothDeg

      public static double cosSmoothDeg(double degrees)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in degrees, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cosDeg(); in particular, only 16384 outputs are possible from cosDeg(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cosDeg() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      degrees - an angle in degrees; most precise between -360 and 360
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • sinSmoothTurns

      public static float sinSmoothTurns(float turns)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in turns, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sinTurns(); in particular, only 16384 outputs are possible from sinTurns(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sinTurns() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      turns - an angle in turns; most precise between -1 and 1
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmoothTurns

      public static float cosSmoothTurns(float turns)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in turns, and takes and returns floats. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cosTurns(); in particular, only 16384 outputs are possible from cosTurns(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cosTurns() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      turns - an angle in turns; most precise between -1 and 1
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • sinSmoothTurns

      public static double sinSmoothTurns(double turns)
      A smooth sine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in turns, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of sinTurns(); in particular, only 16384 outputs are possible from sinTurns(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible sinTurns() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      turns - an angle in turns; most precise between -1 and 1
      Returns:
      the approximate sine of the given angle, from -1 to 1 inclusive
    • cosSmoothTurns

      public static double cosSmoothTurns(double turns)
      A smooth cosine approximation (not table-based) built around Bhaskara I's sine approximation from the 7th century. This takes an input in turns, and takes and returns doubles. This was updated more recently than the 7th century, and has better precision than the original. You may want to use this if you notice statistical issues with the tabular approximation of cosTurns(); in particular, only 16384 outputs are possible from cosTurns(float), and about half of those are duplicates, so if you need more possible results in-between the roughly 8192 possible cosTurns() returns, you can use this.
      Credit to This Stack Exchange answer by WimC.
      Parameters:
      turns - an angle in turns; most precise between -1 and 1
      Returns:
      the approximate cosine of the given angle, from -1 to 1 inclusive
    • atanUnchecked

      public static double 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 in radians, from -HALF_PI to HALF_PI inclusive
    • atanUncheckedTurns

      public static double atanUncheckedTurns(double i)
      A variant on atanTurns(float) that does not tolerate infinite inputs for speed reasons. This can be given a double parameter, but is otherwise the same as atanTurns(float), but returns a double in case external code needs higher precision. It uses the same approximation, from sheet 11 of "Approximations for Digital Computers." This is mostly meant to be used inside atan2Turns(float, float), but it may be a tiny bit faster than atanTurns(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 turns, from -0.25 to 0.25 inclusive
    • 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
    • atan2

      public static float atan2(float y, float x)
      Close approximation of the frequently-used trigonometric method atan2, using radians. 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
    • 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 atan2Deg().
      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.
      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
    • atan2Turns

      public static float atan2Turns(float y, float x)
      Close approximation of the frequently-used trigonometric method atan2, using non-negative turns only. Average absolute error is 0.00000030 turns; relative error is 0 turns; maximum error is 0.00000017 turns. Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in turns. Because this always returns a float between 0.0 (inclusive) and 1.0 (exclusive), it can be useful for various kinds of calculations that must store angles as a small fraction, such as packing a hue angle into a byte.
      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 atan2Turns().
      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 turns as a float; ranges from 0.0f to 1.0f
    • atan2

      public static double atan2(double y, double x)
      Close approximation of the frequently-used trigonometric method atan2, using radians. Average error is 1.057E-6 radians; maximum error is 1.922E-6. Takes y and x (in that unusual order) as doubles, 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(double) 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 double; ranges from -PI to PI
    • atan2Deg

      public static double atan2Deg(double y, double 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 doubles, 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(double) method, and that cleanly translates to atan2Deg().
      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 double; ranges from -180 to 180
    • atan2Deg360

      public static double atan2Deg360(double y, double 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 doubles, 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(double) 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 double; ranges from 0 to 360
    • atan2Turns

      public static double atan2Turns(double y, double x)
      Close approximation of the frequently-used trigonometric method atan2, using non-negative turns only. Average absolute error is 0.00000030 turns; relative error is 0 turns; maximum error is 0.00000017 turns. Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in turns. Because this always returns a double between 0.0 (inclusive) and 1.0 (exclusive), it can be useful for various kinds of calculations that must store angles as a small fraction, such as packing a hue angle into a byte.
      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(double) method, and that cleanly translates to atan2Turns().
      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 turns as a double; ranges from 0.0 to 1.0
    • asin

      public static float asin(float a)
      Returns arcsine 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
    • 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
    • asinTurns

      public static float asinTurns(float a)
      Returns arcsine in turns. This implementation does not return NaN if given an out-of-range input (Math.asin does return NaN), unless the input is NaN. Note that unlike atan2Turns(float, float), this can return negative turn values.
      Parameters:
      a - asin is defined only when a is between -1f and 1f, inclusive
      Returns:
      between -0.25 and 0.25 when a is in the defined range
    • acos

      public static float acos(float a)
      Returns arccosine 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
    • 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
    • acosTurns

      public static float acosTurns(float a)
      Returns arccosine in turns. 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 0.5 when a is in the defined range
    • asin

      public static double asin(double a)
      Returns arcsine 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 -1.0 and 1.0, inclusive
      Returns:
      between -HALF_PI and HALF_PI when a is in the defined range
    • asinDeg

      public static double asinDeg(double 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 -1.0 and 1.0, inclusive
      Returns:
      between -90 and 90 when a is in the defined range
    • asinTurns

      public static double asinTurns(double a)
      Returns arcsine in turns. This implementation does not return NaN if given an out-of-range input (Math.asin does return NaN), unless the input is NaN. Note that unlike atan2Turns(double, double), this can return negative turn values.
      Parameters:
      a - asin is defined only when a is between -1.0 and 1.0, inclusive
      Returns:
      between -0.25 and 0.25 when a is in the defined range
    • acos

      public static double acos(double a)
      Returns arccosine 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 -1.0 and 1.0, inclusive
      Returns:
      between 0 and PI when a is in the defined range
    • acosDeg

      public static double acosDeg(double 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 -1.0 and 1.0, inclusive
      Returns:
      between 0 and 180 when a is in the defined range
    • acosTurns

      public static double acosTurns(double a)
      Returns arccosine in turns. 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 -1.0 and 1.0, inclusive
      Returns:
      between 0 and 0.5 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 in radians, from -HALF_PI to HALF_PI inclusive
      See Also:
    • 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 atanUncheckedDeg() 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:
    • atanTurns

      public static float atanTurns(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). For finite inputs only, you may get a tiny speedup by using atanUncheckedTurns(double), but this method will be correct enough for infinite inputs, and atanUncheckedTurns() 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 turns, from -0.25 to 0.25 inclusive
      See Also:
    • atan

      public static double atan(double 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 double is accepted
      Returns:
      an output from the inverse tangent function in radians, from -HALF_PI to HALF_PI inclusive
      See Also:
    • atanDeg

      public static double atanDeg(double 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 atanUncheckedDeg() will not be.
      Parameters:
      i - an input to the inverse tangent function; any double is accepted
      Returns:
      an output from the inverse tangent function in degrees, from -90 to 90 inclusive
      See Also:
    • atanTurns

      public static double atanTurns(double 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). For finite inputs only, you may get a tiny speedup by using atanUncheckedTurns(double), but this method will be correct enough for infinite inputs, and atanUncheckedTurns() will not be.
      Parameters:
      i - an input to the inverse tangent function; any double is accepted
      Returns:
      an output from the inverse tangent function in turns, from -0.25 to 0.25 inclusive
      See Also: