001package squidpony.squidmath; 002 003/** 004 * Various numeric functions that are important to performance but need alternate implementations on GWT to obtain it. 005 * Super-sourced on GWT, but most things here are direct calls to JDK methods when on desktop or Android. 006 * Some of this code makes use of "creative" bit manipulation of floats and doubles, which can sometimes allow uncommon 007 * input-to-output patterns (as in {@link #bounce(float)}), or even can yield a performance boost (compare 008 * {@link #zigzag(float)} to using modulus to accomplish the same results). The bit manipulation has good performance on 009 * GWT thanks to JS typed arrays, which are well-supported now across all recent browsers and have fallbacks in GWT in 010 * the unlikely event of a browser not supporting them. 011 */ 012public final class NumberTools { 013 /** 014 * Identical to {@link Double#doubleToLongBits(double)} on desktop; optimized on GWT. When compiling to JS via GWT, 015 * there is no way to distinguish NaN values with different bits but that are still NaN, so this doesn't try to 016 * somehow permit that. Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and 017 * have fallbacks in GWT in the unlikely event of a browser not supporting them. JS typed arrays support double, but 018 * not long, so this needs to compose a long from two ints, which means the double-to/from-long conversions aren't 019 * as fast as float-to/from-int conversions. 020 * @param value a {@code double} floating-point number. 021 * @return the bits that represent the floating-point number. 022 */ 023 public static long doubleToLongBits(final double value) 024 { 025 return Double.doubleToLongBits(value); 026 } 027 /** 028 * Identical to {@link Double#doubleToLongBits(double)} on desktop (note, not 029 * {@link Double#doubleToRawLongBits(double)}); optimized on GWT. When compiling to JS via GWT, there is no way to 030 * distinguish NaN values with different bits but that are still NaN, so this doesn't try to somehow permit that. 031 * Uses JS typed arrays on GWT, which are well-supported now across all recent browsers and have fallbacks in GWT in 032 * the unlikely event of a browser not supporting them. JS typed arrays support double, but not long, so this needs 033 * to compose a long from two ints, which means the double-to/from-long conversions aren't as fast as 034 * float-to/from-int conversions. 035 * @param value a {@code double} floating-point number. 036 * @return the bits that represent the floating-point number. 037 */ 038 public static long doubleToRawLongBits(final double value) 039 { 040 return Double.doubleToLongBits(value); 041 } 042 043 /** 044 * Identical to {@link Double#longBitsToDouble(long)} on desktop; optimized on GWT. Uses JS typed arrays on GWT, 045 * which are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a 046 * browser not supporting them. JS typed arrays support double, but not long, so this needs to compose a long from 047 * two ints, which means the double-to/from-long conversions aren't as fast as float-to/from-int conversions. 048 * @param bits a long. 049 * @return the {@code double} floating-point value with the same bit pattern. 050 */ 051 public static double longBitsToDouble(final long bits) 052 { 053 return Double.longBitsToDouble(bits); 054 } 055 /** 056 * Converts {@code value} to a long and gets the lower 32 bits of that long, as an int. 057 * @param value a {@code double} precision floating-point number. 058 * @return the lower half of the bits that represent the floating-point number, as an int. 059 */ 060 public static int doubleToLowIntBits(final double value) 061 { 062 return (int)(Double.doubleToLongBits(value) & 0xffffffffL); 063 } 064 065 /** 066 * Converts {@code value} to a long and gets the upper 32 bits of that long, as an int. 067 * @param value a {@code double} precision floating-point number. 068 * @return the upper half of the bits that represent the floating-point number, as an int. 069 */ 070 public static int doubleToHighIntBits(final double value) 071 { 072 return (int)(Double.doubleToLongBits(value) >>> 32); 073 } 074 075 /** 076 * Converts {@code value} to a long and gets the XOR of its upper and lower 32-bit sections. Useful for numerical 077 * code where a 64-bit double needs to be reduced to a 32-bit value with some hope of keeping different doubles 078 * giving different ints. 079 * @param value a {@code double} precision floating-point number. 080 * @return the XOR of the lower and upper halves of the bits that represent the floating-point number. 081 */ 082 public static int doubleToMixedIntBits(final double value) 083 { 084 final long l = Double.doubleToLongBits(value); 085 return (int)(l & 0xFFFFFFFFL) ^ (int)(l >>> 32); 086 } 087 088 /** 089 * Makes a modified version of value that uses the specified bits (up to 12) for its exponent and sign. 090 * Meant for some specific cases, like adjusting the exponent on an unknown double to the 1.0 to 2.0 range (which 091 * would pass 0x3ff for exponentBits). If you have a double from 1.0 to 2.0, you can subtract 1.0 from it to get the 092 * often-desirable 0.0-1.0 range. Other common cases are 0x400, which adjusts to between 2.0 and 4.0 (subtracting 093 * 3.0 from this gives the -1.0 to 1.0 range, useful for noise), and 0xBFF, which adjusts to between -2.0 and -1.0. 094 * For the last case, you might think that -0x3ff would work, but sadly it doesn't. You can use 095 * {@code exponentBits |= 0x800} to set the sign bit to negative, or {@code exponentBits &= 0x7ff} for positive. 096 * @param value a double that will have its sign and exponent set to the specified bits 097 * @param exponentBits the bits to use for the sign and exponent section of the returned modification of value 098 * @return the double produced by keeping the significand of value but changing its exponent and sign as given 099 */ 100 public static double setExponent(final double value, final int exponentBits) 101 { 102 return Double.longBitsToDouble((Double.doubleToLongBits(value) & 0xfffffffffffffL) | ((long) exponentBits << 52)); 103 } 104 105 /** 106 * Gets an 8-bit section of the given double {@code value}, using {@code whichByte} to select whether this should 107 * return byte 0 (least significant), 1, 2, and so on up to 7 (most significant). 108 * @param value a float 109 * @param whichByte an int that will be used to select the byte to take from value (any int is allowed, only the bottom 3 bits are used to select) 110 * @return the selected byte from the given float 111 */ 112 public static byte getSelectedByte(final double value, final int whichByte) 113 { 114 return (byte)(Double.doubleToLongBits(value) >>> ((whichByte & 7) << 3)); 115 } 116 117 /** 118 * Like {@link #getSelectedByte(double, int)}, this sets the byte at a selected position in the int representation of 119 * a double, then returns the double produced by the bit change. Uses {@code whichByte} to select whether this should 120 * set byte 0 (least significant), 1, 2, and so on up to 7 (most significant). {@code newValue} is a byte. 121 * @param value a double 122 * @param whichByte an int that will be used to select the byte to take from value (any int is allowed, only the bottom 3 bits are used to select) 123 * @param newValue a byte that will be placed into the returned double's bits at the selected position 124 * @return a double that results from changing the bits at the selected position to match newValue 125 */ 126 public static double setSelectedByte(final double value, final int whichByte, final byte newValue) 127 { 128 return Double.longBitsToDouble((Double.doubleToLongBits(value) & ~(255 << ((whichByte & 7) << 3))) 129 | ((newValue & 255) << ((whichByte & 7) << 3))); 130 } 131 132 /** 133 * Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing 134 * close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to 135 * limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. 136 * @param value any double 137 * @return a double from -1.0 (inclusive) to 1.0 (exclusive) 138 */ 139 public static double bounce(final double value) 140 { 141 final long s = Double.doubleToLongBits(value); 142 return Double.longBitsToDouble(((s ^ -((s & 0x8000000000000L)>>51)) & 0xfffffffffffffL) 143 | 0x4010000000000000L) - 5.0; 144 } 145 146 /** 147 * Very limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing 148 * close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to 149 * limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. 150 * @param value any double 151 * @return a double from -1.0 (inclusive) to 1.0 (exclusive) 152 */ 153 public static float bounce(final float value) 154 { 155 final int s = Float.floatToIntBits(value); 156 return Float.intBitsToFloat(((s ^ -((s & 0x00400000)>>22)) & 0x007fffff) 157 | 0x40800000) - 5f; 158 } 159 /** 160 * Very limited-use; takes the significand bits of a double, represented as a long of which this uses 52 bits, and 161 * produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and 162 * down through the range. This is meant for noise, where it may be useful to limit the amount of change between 163 * nearby points' noise values and prevent sudden "jumps" in noise value. 164 * @param value any long; only the lower 52 bits will be used 165 * @return a double from -1.0 (inclusive) to 1.0 (exclusive) 166 */ 167 public static double bounce(final long value) 168 { 169 return Double.longBitsToDouble(((value ^ -((value & 0x8000000000000L)>>51)) & 0xfffffffffffffL) 170 | 0x4010000000000000L) - 5.0; 171 } 172 /** 173 * Very limited-use; takes the significand bits of a double, represented as a pair of ints {@code valueLow} and 174 * {@code valueHigh}, using all bits in valueLow and the least-significant 20 bits of valueHigh, and 175 * produces a double in the -1.0 to 1.0 range, with similar inputs producing close to a consistent rate of up and 176 * down through the range. This is meant for noise, where it may be useful to limit the amount of change between 177 * nearby points' noise values and prevent sudden "jumps" in noise value. 178 * @param valueLow any int; all bits will be used as the less-significant bits of the significand 179 * @param valueHigh any int; only the bottom 20 bits will be used as the more-significant bits of the significand 180 * @return a double from -1.0 (inclusive) to 1.0 (exclusive) 181 */ 182 183 public static double bounce(final int valueLow, final int valueHigh) 184 { 185 final long s = (((long) valueHigh) << 32 | valueLow); 186 return Double.longBitsToDouble(((s ^ -((s & 0x8000000000000L)>>51)) & 0xfffffffffffffL) 187 | 0x4010000000000000L) - 5.0; 188 } 189 190 /** 191 * Limited-use; takes any double and produces a double in the -1.0 to 1.0 range, with similar inputs producing 192 * close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to 193 * limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. It is 194 * very similar to {@link #bounce(double)}, but unlike bounce() this will maintain a continuous rate regardless of 195 * the magnitude of its input. An input of any even number should produce something very close to -1.0, any odd 196 * number should produce something very close to 1.0, and any number halfway between two incremental integers (like 197 * 8.5 or -10.5) should produce 0.0 or a very small fraction. This method is closely related to 198 * {@link #sway(double)}, which will smoothly curve its output to produce more values that are close to -1 or 1. 199 * @param value any double 200 * @return a double from -1.0 (inclusive) to 1.0 (inclusive) 201 */ 202 public static double zigzag(double value) 203 { 204 long floor = (value >= 0.0 ? (long) value : (long) value - 1L); 205 value -= floor; 206 floor = (-(floor & 1L) | 1L); 207 return value * (floor << 1) - floor; 208 } 209 210 /** 211 * Limited-use; takes any float and produces a float in the -1f to 1f range, with similar inputs producing 212 * close to a consistent rate of up and down through the range. This is meant for noise, where it may be useful to 213 * limit the amount of change between nearby points' noise values and prevent sudden "jumps" in noise value. It is 214 * very similar to {@link #bounce(float)}, but unlike bounce() this will maintain a continuous rate regardless of 215 * the magnitude of its input. An input of any even number should produce something very close to -1f, any odd 216 * number should produce something very close to 1f, and any number halfway between two incremental integers (like 217 * 8.5f or -10.5f) should produce 0f or a very small fraction. This method is closely related to 218 * {@link #sway(float)}, which will smoothly curve its output to produce more values that are close to -1 or 1. 219 * @param value any float 220 * @return a float from -1f (inclusive) to 1f (inclusive) 221 */ 222 public static float zigzag(float value) 223 { 224 int floor = (value >= 0f ? (int) value : (int) value - 1); 225 value -= floor; 226 floor = (-(floor & 1) | 1); 227 return value * (floor << 1) - floor; 228 } 229 230 /** 231 * Limited-use; takes any double and produces a double in the -1 to 1 range, with a graph of input to output that 232 * looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the 233 * input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for 234 * noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both 235 * sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very 236 * similar to {@link #bounce(double)} and {@link #zigzag(double)}, but unlike bounce() this will maintain its 237 * frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough 238 * floating-point precision to represent changes smaller than 1.0), and unlike zigzag() this will smooth its path. 239 * An input of any even number should produce something very close to -1.0, any odd number should produce something 240 * very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 0.0 241 * or a very small fraction. In the (unlikely) event that this is given a double that is too large to represent 242 * many or any non-integer values, this will simply return -1.0 or 1.0. 243 * @param value any double other than NaN or infinite values; extremely large values can't work properly 244 * @return a double from -1.0 (inclusive) to 1.0 (inclusive) 245 */ 246 public static double sway(double value) 247 { 248 long floor = (value >= 0.0 ? (long) value : (long) value - 1L); 249 value -= floor; 250 floor = (-(floor & 1L) | 1L); 251 return value * value * value * (value * (value * 6.0 - 15.0) + 10.0) * (floor << 1) - floor; 252 } 253 254 /** 255 * Limited-use; takes any float and produces a float in the -1f to 1f range, with a graph of input to output that 256 * looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the 257 * input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for 258 * noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both 259 * sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very 260 * similar to {@link #bounce(float)} and {@link #zigzag(float)}, but unlike bounce() this will maintain its 261 * frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough 262 * floating-point precision to represent changes smaller than 1f), and unlike zigzag() this will smooth its path. 263 * An input of any even number should produce something very close to -1f, any odd number should produce something 264 * very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 0f 265 * or a very small fraction. In the (unlikely) event that this is given a float that is too large to represent 266 * many or any non-integer values, this will simply return -1f or 1f. 267 * @param value any float other than NaN or infinite values; extremely large values can't work properly 268 * @return a float from -1f (inclusive) to 1f (inclusive) 269 */ 270 public static float sway(float value) 271 { 272 int floor = (value >= 0f ? (int) value : (int) value - 1); 273 value -= floor; 274 floor = (-(floor & 1) | 1); 275 return value * value * value * (value * (value * 6f - 15f) + 10f) * (floor << 1) - floor; 276 } 277 278 /** 279 * Limited-use; takes any float and produces a float in the 0f to 1f range, with a graph of input to output that 280 * looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the 281 * input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for 282 * noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both 283 * sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very 284 * similar to {@link #bounce(float)} and {@link #zigzag(float)}, but unlike bounce() this will not change its 285 * frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough 286 * floating-point precision to represent changes smaller than 1f), and unlike zigzag() this will smooth its path. 287 * An input of any even number should produce something very close to 0f, any odd number should produce something 288 * very close to 1f, and any number halfway between two incremental integers (like 8.5f or -10.5f) should produce 289 * 0.5f. In the (unlikely) event that this is given a float that is too large to represent many or any non-integer 290 * values, this will simply return 0f or 1f. This version is called "Tight" because its range is tighter than 291 * {@link #sway(float)}. 292 * @param value any float other than NaN or infinite values; extremely large values can't work properly 293 * @return a float from 0f (inclusive) to 1f (inclusive) 294 */ 295 public static float swayTight(float value) 296 { 297 int floor = (value >= 0f ? (int) value : (int) value - 1); 298 value -= floor; 299 floor &= 1; 300 return value * value * value * (value * (value * 6f - 15f) + 10f) * (-floor | 1) + floor; 301 } 302 303 /** 304 * Limited-use; takes any double and produces a double in the 0.0 to 1.0 range, with a graph of input to output that 305 * looks much like a sine wave, curving to have a flat slope when given an integer input and a steep slope when the 306 * input is halfway between two integers, smoothly curving at any points between those extremes. This is meant for 307 * noise, where it may be useful to limit the amount of change between nearby points' noise values and prevent both 308 * sudden "jumps" in noise value and "cracks" where a line takes a sudden jagged movement at an angle. It is very 309 * similar to {@link #bounce(double)} and {@link #zigzag(double)}, but unlike bounce() this will not change its 310 * frequency of returning max or min values, regardless of the magnitude of its input (as long as there is enough 311 * floating-point precision to represent changes smaller than 1.0), and unlike zigzag() this will smooth its path. 312 * An input of any even number should produce something very close to 0.0, any odd number should produce something 313 * very close to 1.0, and any number halfway between two incremental integers (like 8.5 or -10.5) should produce 314 * 0.5f. In the (unlikely) event that this is given a double that is too large to represent many or any non-integer 315 * values, this will simply return 0.0 or 1.0. This version is called "Tight" because its range is tighter than 316 * {@link #sway(double)}. 317 * @param value any double other than NaN or infinite values; extremely large values can't work properly 318 * @return a double from 0.0 (inclusive) to 1.0 (inclusive) 319 */ 320 public static double swayTight(double value) 321 { 322 long floor = (value >= 0.0 ? (long) value : (long) value - 1L); 323 value -= floor; 324 floor &= 1L; 325 return value * value * value * (value * (value * 6.0 - 15.0) + 10.0) * (-floor | 1L) + floor; 326 } 327 328 /** 329 * A mix of the smooth transitions of {@link #sway(double)} with (seeded) random peaks and valleys between -1.0 and 330 * 1.0 (both exclusive). The pattern this will produces will be completely different if the seed changes, and it is 331 * suitable for 1D noise. Uses a simple method of cubic interpolation between random values, where a random value is 332 * used without modification when given an integer for {@code value}. Note that this uses a different type of 333 * interpolation than {@link #sway(double)}, which uses quintic (this causes swayRandomized() to produce more 334 * outputs in the mid-range and less at extremes; it is also slightly faster and simpler). 335 * <br> 336 * Performance note: HotSpot seems to be much more able to optimize swayRandomized(long, float) than 337 * swayRandomized(long, double), with the float version almost twice as fast after JIT warms up. On GWT, the 338 * reverse should be expected because floats must be emulated there. 339 * @param seed a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between calls 340 * @param value a double that typically changes slowly, by less than 1.0, with direction changes at integer inputs 341 * @return a pseudo-random double between -1.0 and 1.0 (both exclusive), smoothly changing with value 342 */ 343 public static double swayRandomized(long seed, double value) 344 { 345 final long floor = value >= 0.0 ? (long) value : (long) value - 1L; // the closest long that is less than value 346 // gets a random start and endpoint. there's a sequence of start and end values for each seed, and changing the 347 // seed changes the start and end values unpredictably (so use the same seed for one curving line). 348 final double start = (((seed += floor * 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) * 0x0.fffffffffffffbp-63, 349 end = (((seed += 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) * 0x0.fffffffffffffbp-63; 350 // gets the fractional part of value 351 value -= floor; 352 // cubic interpolation to smooth the curve 353 value *= value * (3.0 - 2.0 * value); 354 // interpolate between start and end based on how far we are between the start and end points of this section 355 return (1.0 - value) * start + value * end; 356 } 357 358 /** 359 * A mix of the smooth transitions of {@link #sway(float)} with (seeded) random peaks and valleys between -1f and 360 * 1f (both exclusive). The pattern this will produces will be completely different if the seed changes, and it is 361 * suitable for 1D noise. Uses a simple method of cubic interpolation between random values, where a random value is 362 * used without modification when given an integer for {@code value}. Note that this uses a different type of 363 * interpolation than {@link #sway(float)}, which uses quintic (this causes swayRandomized() to produce more 364 * outputs in the mid-range and less at extremes; it is also slightly faster and simpler). 365 * <br> 366 * Performance note: HotSpot seems to be much more able to optimize swayRandomized(long, float) than 367 * swayRandomized(long, double), with the float version almost twice as fast after JIT warms up. On GWT, the 368 * reverse should be expected because floats must be emulated there. 369 * @param seed a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between calls 370 * @param value a float that typically changes slowly, by less than 2.0, with direction changes at integer inputs 371 * @return a pseudo-random float between -1f and 1f (both exclusive), smoothly changing with value 372 */ 373 public static float swayRandomized(long seed, float value) 374 { 375 final long floor = value >= 0f ? (long) value : (long) value - 1L; 376 final float start = (((seed += floor * 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) * 0x0.ffffffp-63f, 377 end = (((seed += 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) * 0x0.ffffffp-63f; 378 value -= floor; 379 value *= value * (3f - 2f * value); 380 return (1f - value) * start + value * end; 381 } 382 383 /** 384 * A variant on {@link #swayRandomized(long, double)} that takes an int seed instead of a long, and is optimized for 385 * usage on GWT. Like the version with a long seed, this uses cubic interpolation between random peak or valley 386 * points; only the method of generating those random peaks and valleys has changed. 387 * @param seed an int seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between calls 388 * @param value a double that typically changes slowly, by less than 2.0, with direction changes at integer inputs 389 * @return a pseudo-random double between -1.0 and 1.0 (both exclusive), smoothly changing with value 390 */ 391 public static double swayRandomized(final int seed, double value) 392 { 393 final int floor = value >= 0.0 ? (int) value : (int) value - 1; 394 int z = seed + floor; 395 final double start = (((z = (z ^ 0xD1B54A35) * 0x1D2BC3)) * ((z ^ z >>> 15) | 0xFFE00001) ^ z ^ z << 11) * 0x0.ffffffp-31, 396 end = (((z = (seed + floor + 1 ^ 0xD1B54A35) * 0x1D2BC3)) * ((z ^ z >>> 15) | 0xFFE00001) ^ z ^ z << 11) * 0x0.ffffffp-31; 397 value -= floor; 398 value *= value * (3.0 - 2.0 * value); 399 return (1.0 - value) * start + value * end; 400 } 401 402 /** 403 * A variant on {@link #swayRandomized(long, float)} that takes an int seed instead of a long, and is optimized for 404 * usage on GWT. Like the version with a long seed, this uses cubic interpolation between random peak or valley 405 * points; only the method of generating those random peaks and valleys has changed. 406 * @param seed an int seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between calls 407 * @param value a float that typically changes slowly, by less than 2.0, with direction changes at integer inputs 408 * @return a pseudo-random float between -1f and 1f (both exclusive), smoothly changing with value 409 */ 410 public static float swayRandomized(final int seed, float value) 411 { 412 final int floor = value >= 0f ? (int) value : (int) value - 1; 413 int z = seed + floor; 414 final float start = (((z = (z ^ 0xD1B54A35) * 0x102473) ^ (z << 11 | z >>> 21) ^ (z << 19 | z >>> 13)) * ((z ^ z >>> 15) | 0xFFE00001) ^ z) * 0x0.ffffffp-31f, 415 end = (((z = (seed + floor + 1 ^ 0xD1B54A35) * 0x102473) ^ (z << 11 | z >>> 21) ^ (z << 19 | z >>> 13)) * ((z ^ z >>> 15) | 0xFFE00001) ^ z) * 0x0.ffffffp-31f; 416 value -= floor; 417 value *= value * (3 - 2 * value); 418 return (1 - value) * start + value * end; 419 } 420 /** 421 * A 1D "noise" method that produces smooth transitions like {@link #sway(float)}, but also wrapping around at pi * 422 * 2 so this can be used to get smoothly-changing random angles. Has (seeded) random peaks and valleys where it 423 * slows its range of change, but can return any value from 0 to 6.283185307179586f, or pi * 2. The pattern this 424 * will produces will be completely different if the seed changes, and the value is expected to be something other 425 * than an angle, like time. Uses a simple method of cubic interpolation between random values, where a random value 426 * is used without modification when given an integer for {@code value}. Note that this uses a different type of 427 * interpolation than {@link #sway(float)}, which uses quintic (this causes swayAngleRandomized() to be slightly 428 * faster and simpler). 429 * @param seed a long seed that will determine the pattern of peaks and valleys this will generate as value changes; this should not change between calls 430 * @param value a float that typically changes slowly, by less than 1.0, with possible direction changes at integer inputs 431 * @return a pseudo-random float between 0f and 283185307179586f (both inclusive), smoothly changing with value and wrapping 432 */ 433 public static float swayAngleRandomized(long seed, float value) 434 { 435 final long floor = value >= 0f ? (long) value : (long) value - 1L; 436 float start = (((seed += floor * 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L) >>> 1) * 0x0.ffffffp-62f, 437 end = (((seed += 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L) >>> 1) * 0x0.ffffffp-62f; 438 value -= floor; 439 value *= value * (3f - 2f * value); 440 end = end - start + 1.5f; 441 end -= (long)end + 0.5f; 442 start += end * value + 1; 443 return (start - (long)start) * 6.283185307179586f; 444 } 445 446 /** 447 * Identical to {@link Float#floatToIntBits(float)} on desktop; optimized on GWT. Uses JS typed arrays on GWT, which 448 * are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser 449 * not supporting them. 450 * @param value a floating-point number. 451 * @return the bits that represent the floating-point number. 452 */ 453 public static int floatToIntBits(final float value) 454 { 455 return Float.floatToIntBits(value); 456 } 457 /** 458 * Identical to {@link Float#floatToIntBits(float)} on desktop (note, not {@link Float#floatToRawIntBits(float)}); 459 * optimized on GWT. When compiling to JS via GWT, there is no way to distinguish NaN values with different bits but 460 * that are still NaN, so this doesn't try to somehow permit that. Uses JS typed arrays on GWT, which are 461 * well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser not 462 * supporting them. 463 * @param value a floating-point number. 464 * @return the bits that represent the floating-point number. 465 */ 466 public static int floatToRawIntBits(final float value) 467 { 468 return Float.floatToIntBits(value); 469 } 470 471 472 /** 473 * Gets the bit representation of the given float {@code value}, but with reversed byte order. On desktop, this is 474 * equivalent to calling {@code Integer.reverseBytes(Float.floatToIntBits(value))}, but it is implemented using 475 * typed arrays on GWT. 476 * @param value a floating-point number 477 * @return the bits that represent the floating-point number, with their byte order reversed from normal. 478 */ 479 public static int floatToReversedIntBits(final float value) { 480 return Integer.reverseBytes(Float.floatToIntBits(value)); 481 } 482 483 /** 484 * Reverses the byte order of {@code bits} and converts that to a float. On desktop, this is 485 * equivalent to calling {@code Float.intBitsToFloat(Integer.reverseBytes(bits))}, but it is implemented using 486 * typed arrays on GWT. 487 * @param bits an integer 488 * @return the {@code float} floating-point value with the given bits using their byte order reversed from normal. 489 */ 490 public static float reversedIntBitsToFloat(final int bits) { 491 return Float.intBitsToFloat(Integer.reverseBytes(bits)); 492 } 493 494 /** 495 * Identical to {@link Float#intBitsToFloat(int)} on desktop; optimized on GWT. Uses JS typed arrays on GWT, which 496 * are well-supported now across all recent browsers and have fallbacks in GWT in the unlikely event of a browser 497 * not supporting them. 498 * @param bits an integer. 499 * @return the {@code float} floating-point value with the same bit pattern. 500 */ 501 public static float intBitsToFloat(final int bits) 502 { 503 return Float.intBitsToFloat(bits); 504 } 505 506 /** 507 * Gets an 8-bit section of the given float {@code value}, using {@code whichByte} to select whether this should 508 * return byte 0 (least significant), 1, 2, or 3 (most significant). 509 * @param value a float 510 * @param whichByte an int that will be used to select the byte to take from value (any int is allowed, only the bottom 2 bits are used to select) 511 * @return the selected byte from the given float 512 */ 513 public static byte getSelectedByte(final float value, final int whichByte) 514 { 515 return (byte)(Float.floatToIntBits(value) >>> ((whichByte & 3) << 3)); 516 } 517 518 /** 519 * Like {@link #getSelectedByte(float, int)}, this sets the byte at a selected position in the int representation of 520 * a float, then returns the float produced by the bit change. Uses {@code whichByte} to select whether this should 521 * set byte 0 (least significant), 1, 2, or 3 (most significant). {@code newValue} is a byte. 522 * @param value a float 523 * @param whichByte an int that will be used to select the byte to take from value (any int is allowed, only the bottom 2 bits are used to select) 524 * @param newValue a byte that will be placed into the returned float's bits at the selected position 525 * @return a float that results from changing the bits at the selected position to match newValue 526 */ 527 public static float setSelectedByte(final float value, final int whichByte, final byte newValue) 528 { 529 return Float.intBitsToFloat((Float.floatToIntBits(value) & ~(255 << ((whichByte & 3) << 3))) 530 | ((newValue & 255) << ((whichByte & 3) << 3))); 531 } 532 533 /** 534 * Generates a pseudo-random double between 0.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing 535 * it once through the (decent-quality and very fast) {@link ThrustAltRNG} algorithm. 536 * <br> 537 * Consider calling this with {@code NumberTools.randomDouble(++seed)} for an optimal period of 2 to the 64 when 538 * repeatedly called, but {@code NumberTools.randomDouble(seed += ODD_LONG)} will also work just fine if ODD_LONG is 539 * any odd-number long, positive or negative. 540 * @param seed any long to be used as a seed 541 * @return a pseudo-random double from 0.0 (inclusive) to 1.0 (exclusive) 542 */ 543 public static double randomDouble(long seed) 544 { 545 return (((seed = ((seed *= 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) ^ (seed >>> 23)) & 0x1FFFFFFFFFFFFFL) * 0x1p-53; 546 } 547 548 /** 549 * Generates a pseudo-random double between -1.0 (inclusive) and 1.0 (exclusive) using the given long seed, passing 550 * it once through the (decent-quality and very fast) {@link ThrustAltRNG} algorithm. 551 * <br> 552 * Consider calling this with {@code NumberTools.randomSignedDouble(++seed)} for an optimal period of 2 to the 64 553 * when repeatedly called, but {@code NumberTools.randomSignedDouble(seed += ODD_LONG)} will also work just fine if 554 * ODD_LONG is any odd-number long, positive or negative. 555 * @param seed any long to be used as a seed 556 * @return a pseudo-random double from 0.0 (inclusive) to 1.0 (exclusive) 557 */ 558 public static double randomSignedDouble(long seed) 559 { 560 return (((seed = ((seed *= 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) ^ (seed >>> 23)) >> 10) * 0x1p-53; 561 } 562 /** 563 * Generates a pseudo-random float between 0f (inclusive) and 1f (exclusive) using the given long seed, passing it 564 * once through the (decent-quality and very fast) {@link ThrustAltRNG} algorithm. 565 * <br> 566 * Consider calling this with {@code NumberTools.randomFloat(++seed)} for an optimal period of 2 to the 64 when 567 * repeatedly called, but {@code NumberTools.randomFloat(seed += ODD_LONG)} will also work just fine if ODD_LONG is 568 * any odd-number long, positive or negative. 569 * @param seed any long to be used as a seed 570 * @return a pseudo-random float from -1.0f (exclusive) to 1.0f (exclusive) 571 */ 572 public static float randomFloat(long seed) 573 { 574 return (((seed = ((seed *= 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) ^ (seed >>> 23)) & 0xFFFFFF) * 0x1p-24f; 575 } 576 /** 577 * Generates a pseudo-random float between -1f (inclusive) and 1f (exclusive) using the given long seed, passing 578 * it once through the (decent-quality and very fast) {@link ThrustAltRNG} algorithm. This can be useful as a 579 * multiplier that has approximately equal likelihood of changing or leaving the sign of its multiplicand, and won't 580 * make the result larger (more significant) but will usually make it closer to 0. 581 * <br> 582 * Consider calling this with {@code NumberTools.randomDouble(++seed)} for an optimal period of 2 to the 64 when 583 * repeatedly called, but {@code NumberTools.randomDouble(seed += ODD_LONG)} will also work just fine if ODD_LONG is 584 * any odd-number long, positive or negative. 585 * @param seed any long to be used as a seed 586 * @return a pseudo-random float from -1.0f (exclusive) to 1.0f (exclusive) 587 */ 588 public static float randomSignedFloat(long seed) 589 { 590 return (((seed = ((seed *= 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) ^ (seed >>> 23)) >> 39) * 0x1p-24f; 591 } 592 593 /** 594 * Generates a pseudo-random double between -1.0 (exclusive) and 1.0 (exclusive) with a distribution that has a 595 * strong central bias (around 0.0). Uses the given long seed, passing it once through the (decent-quality and very 596 * fast) {@link ThrustAltRNG} algorithm. This produces a pseudo-random long, which this simply passes to 597 * {@link #formCurvedFloat(long)}, since it is already well-suited to generating a curved distribution. 598 * <br> 599 * Consider calling this with {@code NumberTools.randomFloatCurved(++seed)} for an optimal period of 2 to the 64 600 * when repeatedly called, but {@code NumberTools.randomFloatCurved(seed += ODD_LONG)} will also work just fine if 601 * ODD_LONG is any odd-number long, positive or negative. 602 * @param seed any int to be used as a seed 603 * @return a pseudo-random double from -1.0 (exclusive) to 1.0 (exclusive), distributed on a curve centered on 0.0 604 */ 605 public static float randomFloatCurved(long seed) 606 { 607 return formCurvedFloat(((seed = ((seed *= 0x6C8E9CF570932BD5L) ^ (seed >>> 25)) * (seed | 0xA529L)) ^ (seed >>> 23))); 608 } 609 610 /** 611 * Given an int as a seed, this uses its least-significant 23 bits to produce a float between 0f (inclusive) and 1f 612 * (exclusive). This does not randomize the seed at all, and the upper 9 bits of the seed are ignored. 613 * @param seed an int; only the bottom 23 bits will be used 614 * @return a float between 0f (inclusive) and 1f (exclusive) 615 */ 616 public static float formFloat(final int seed) 617 { 618 return Float.intBitsToFloat((seed & 0x7FFFFF) | 0x3f800000) - 1f; 619 } 620 /** 621 * Given an int as a seed, this uses its least-significant 23 bits to produce a float between -1f (inclusive) and 1f 622 * (exclusive). This does not randomize the seed at all, and the upper 9 bits of the seed are ignored. 623 * @param seed an int; only the bottom 23 bits will be used 624 * @return a float between -1f (inclusive) and 1f (exclusive) 625 */ 626 public static float formSignedFloat(final int seed) 627 { 628 return Float.intBitsToFloat((seed & 0x7FFFFF) | 0x40000000) - 3f; 629 } 630 631 /** 632 * Given a long as a seed, this uses its least-significant 52 bits to produce a double between 0 (inclusive) and 1 633 * (exclusive). This does not randomize the seed at all, and the upper 12 bits of the seed are ignored. 634 * @param seed a long; only the bottom 52 bits will be used 635 * @return a double between 0 (inclusive) and 1 (exclusive) 636 */ 637 public static double formDouble(final long seed) 638 { 639 return Double.longBitsToDouble((seed & 0xfffffffffffffL) | 0x3ff0000000000000L) - 1f; 640 } 641 /** 642 * Given a long as a seed, this uses its least-significant 52 bits to produce a double between -1 (inclusive) and 1 643 * (exclusive). This does not randomize the seed at all, and the upper 12 bits of the seed are ignored. 644 * @param seed a long; only the bottom 52 bits will be used 645 * @return a double between -1 (inclusive) and 1 (exclusive) 646 */ 647 public static double formSignedDouble(final long seed) 648 { 649 return Double.longBitsToDouble((seed & 0xfffffffffffffL) | 0x4000000000000000L) - 3f; 650 } 651 652 /** 653 * A different kind of determine-like method that expects to be given a random long and produces a random double 654 * with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. 655 * The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1.0 656 * or 1.0. It cannot produce 1.0, -1.0, or any values further from 0 than those bounds. 657 * @param start a long, usually random, such as one produced by any RandomnessSource; all bits will be used 658 * @return a deterministic double between -1.0 (exclusive) and 1.0 (exclusive); very likely to be close to 0.0 659 */ 660 public static double formCurvedDouble(long start) { 661 return longBitsToDouble((start >>> 12) | 0x3fe0000000000000L) 662 + longBitsToDouble(((start *= 0x2545F4914F6CDD1DL) >>> 12) | 0x3fe0000000000000L) 663 - longBitsToDouble(((start *= 0x2545F4914F6CDD1DL) >>> 12) | 0x3fe0000000000000L) 664 - longBitsToDouble(((start * 0x2545F4914F6CDD1DL) >>> 12) | 0x3fe0000000000000L) 665 ; 666 } 667 /** 668 * A different kind of determine-like method that expects to be given a random long and produces a random double 669 * with a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach 0.0 and 1.0. 670 * The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near 0.0 or 671 * 1.0. It cannot produce 0.0, 1.0, or any values further from 0.5 than those bounds. 672 * @param start a long, usually random, such as one produced by any RandomnessSource; all bits will be used 673 * @return a deterministic double between 0.0 (exclusive) and 1.0 (exclusive); very likely to be close to 0.5 674 */ 675 public static double formCurvedDoubleTight(long start) { 676 return 0.5 677 + longBitsToDouble((start >>> 12) | 0x3fd0000000000000L) 678 + longBitsToDouble(((start *= 0x2545F4914F6CDD1DL) >>> 12) | 0x3fd0000000000000L) 679 - longBitsToDouble(((start *= 0x2545F4914F6CDD1DL) >>> 12) | 0x3fd0000000000000L) 680 - longBitsToDouble(((start * 0x2545F4914F6CDD1DL) >>> 12) | 0x3fd0000000000000L); 681 } 682 683 /** 684 * A different kind of determine-like method that expects to be given a random long and produces a random float with 685 * a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. 686 * The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 687 * 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds. 688 * @param start a long, usually random, such as one produced by any RandomnessSource 689 * @return a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f 690 */ 691 public static float formCurvedFloat(final long start) { 692 return intBitsToFloat((int)start >>> 9 | 0x3F000000) 693 + intBitsToFloat((int) (start >>> 41) | 0x3F000000) 694 - intBitsToFloat(((int)(start ^ ~start >>> 20) & 0x007FFFFF) | 0x3F000000) 695 - intBitsToFloat(((int) (~start ^ start >>> 30) & 0x007FFFFF) | 0x3F000000) 696 ; 697 } 698 699 /** 700 * A different kind of determine-like method that expects to be given random ints and produces a random float with 701 * a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. 702 * The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 703 * 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds. 704 * @param start1 an int usually random, such as one produced by any RandomnessSource 705 * @param start2 an int usually random, such as one produced by any RandomnessSource 706 * @return a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f 707 */ 708 public static float formCurvedFloat(final int start1, final int start2) { 709 return intBitsToFloat(start1 >>> 9 | 0x3F000000) 710 + intBitsToFloat((~start1 & 0x007FFFFF) | 0x3F000000) 711 - intBitsToFloat(start2 >>> 9 | 0x3F000000) 712 - intBitsToFloat((~start2 & 0x007FFFFF) | 0x3F000000) 713 ; 714 } 715 /** 716 * A different kind of determine-like method that expects to be given a random int and produces a random float with 717 * a curved distribution that centers on 0 (where it has a bias) and can (rarely) approach -1f and 1f. 718 * The distribution for the values is similar to Irwin-Hall, and is frequently near 0 but not too-rarely near -1f or 719 * 1f. It cannot produce 1f, -1f, or any values further from 0 than those bounds. 720 * @param start an int, usually random, such as one produced by any RandomnessSource 721 * @return a deterministic float between -1f (exclusive) and 1f (exclusive), that is very likely to be close to 0f 722 */ 723 public static float formCurvedFloat(final int start) { 724 return intBitsToFloat(start >>> 9 | 0x3F000000) 725 + intBitsToFloat((start & 0x007FFFFF) | 0x3F000000) 726 - intBitsToFloat(((start << 18 & 0x007FFFFF) ^ ~start >>> 14) | 0x3F000000) 727 - intBitsToFloat(((start << 13 & 0x007FFFFF) ^ ~start >>> 19) | 0x3F000000) 728 ; 729 } 730 731 /** 732 * Returns an int value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in 733 * the specified int value. Returns zero if the specified value has no one-bits in its two's complement binary 734 * representation, that is, if it is equal to zero. 735 * <br> 736 * Identical to {@link Integer#lowestOneBit(int)}, but super-sourced to act correctly on GWT. If you have GWT as a 737 * target and do bit manipulation work, double-check everything! An int can be higher than {@link Integer#MAX_VALUE} 738 * or lower than {@link Integer#MIN_VALUE} on GWT, without actually being a long (internally it's a double). This 739 * is especially relevant for the overload of this method that takes and returns a long; 740 * {@link Long#lowestOneBit(long)} does not provide correct results for certain inputs on GWT, such as 741 * -17592186044416L, which it mysteriously returns 0L on, so you should use {@link #lowestOneBit(long)}. 742 * @param num the value whose lowest one bit is to be computed 743 * @return an int value with a single one-bit, in the position of the lowest-order one-bit in the specified value, 744 * or zero if the specified value is itself equal to zero. 745 */ 746 public static int lowestOneBit(int num) 747 { 748 return num & -num; 749 } 750 /** 751 * Returns an long value with at most a single one-bit, in the position of the lowest-order ("rightmost") one-bit in 752 * the specified long value. Returns zero if the specified value has no one-bits in its two's complement binary 753 * representation, that is, if it is equal to zero. 754 * <br> 755 * Identical to {@link Long#lowestOneBit(long)}, but super-sourced to act correctly on GWT. If you have GWT as a 756 * target and do bit manipulation work, double-check everything! An int can be higher than {@link Integer#MAX_VALUE} 757 * or lower than {@link Integer#MIN_VALUE} on GWT, without actually being a long (internally it's a double). This 758 * is especially relevant for this overload (for longs more so than for ints); {@link Long#lowestOneBit(long)} does 759 * not provide correct results for certain inputs on GWT, such as -17592186044416L, which it mysteriously returns 0L 760 * on, so you should use this method. 761 * @param num the value whose lowest one bit is to be computed 762 * @return a long value with a single one-bit, in the position of the lowest-order one-bit in the specified value, 763 * or zero if the specified value is itself equal to zero. 764 */ 765 public static long lowestOneBit(long num) 766 { 767 return num & -num; 768 } 769 770 /** 771 * A fairly-close approximation of {@link Math#sin(double)} that can be significantly faster (between 8x and 80x 772 * faster sin() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise 773 * and sometimes-faster MathUtils.sin() method. Because this method doesn't rely on a 774 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 775 * with this method than with MathUtils. Takes the same arguments Math.sin() does, so one angle in radians, 776 * which may technically be any double (but this will lose precision on fairly large doubles, such as those that are 777 * larger than {@link Long#MAX_VALUE}, because those doubles themselves will lose precision at that scale). This 778 * is closely related to {@link #sway(double)}, but the shape of the output when graphed is almost identical to 779 * sin(). The difference between the result of this method and {@link Math#sin(double)} should be under 0.0011 at 780 * all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for 781 * potentially higher errors, though. 782 * <br> 783 * The error for this double version is extremely close to the float version, {@link #sin(float)}, so you should 784 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 785 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 786 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 787 * and likewise for doubles. 788 * <br> 789 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 790 * by a measurable amount. 791 * <br> 792 * The technique for sine approximation is mostly from 793 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 794 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 795 * @param radians an angle in radians as a double, often from 0 to pi * 2, though not required to be. 796 * @return the sine of the given angle, as a double between -1.0 and 1.0 (both inclusive) 797 */ 798 799 public static double sin(double radians) 800 { 801 radians *= 0.6366197723675814; 802 final long floor = (radians >= 0.0 ? (long) radians : (long) radians - 1L) & -2L; 803 radians -= floor; 804 radians *= 2.0 - radians; 805 return radians * (-0.775 - 0.225 * radians) * ((floor & 2L) - 1L); 806 } 807 808 /** 809 * A fairly-close approximation of {@link Math#cos(double)} that can be significantly faster (between 8x and 80x 810 * faster cos() calls in benchmarking; if you have access to libGDX you should consider its sometimes-more-precise 811 * and sometimes-faster MathUtils.cos() method. Because this method doesn't rely on a 812 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 813 * with this method than with MathUtils. Takes the same arguments Math.cos() does, so one angle in radians, 814 * which may technically be any double (but this will lose precision on fairly large doubles, such as those that are 815 * larger than {@link Long#MAX_VALUE}, because those doubles themselves will lose precision at that scale). This 816 * is closely related to {@link #sway(double)}, but the shape of the output when graphed is almost identical to 817 * cos(). The difference between the result of this method and {@link Math#cos(double)} should be under 0.0011 at 818 * all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for 819 * potentially higher errors, though. 820 * <br> 821 * The error for this double version is extremely close to the float version, {@link #cos(float)}, so you should 822 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 823 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 824 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 825 * and likewise for doubles. 826 * <br> 827 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 828 * by a measurable amount. 829 * The technique for cosine approximation is mostly from 830 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 831 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 832 * @param radians an angle in radians as a double, often from 0 to pi * 2, though not required to be. 833 * @return the cosine of the given angle, as a double between -1.0 and 1.0 (both inclusive) 834 */ 835 public static double cos(double radians) 836 { 837 radians = radians * 0.6366197723675814 + 1.0; 838 final long floor = (radians >= 0.0 ? (long) radians : (long) radians - 1L) & -2L; 839 radians -= floor; 840 radians *= 2.0 - radians; 841 return radians * (-0.775 - 0.225 * radians) * ((floor & 2L) - 1L); 842 } 843 844 /** 845 * A fairly-close approximation of {@link Math#sin(double)} that can be significantly faster (between 8x and 80x 846 * faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should 847 * consider its more-precise and sometimes-faster MathUtils.sin() method. Because this method doesn't rely on a 848 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 849 * with this method than with MathUtils. Takes the same arguments Math.sin() does, so one angle in radians, 850 * which may technically be any float (but this will lose precision on fairly large floats, such as those that are 851 * larger than {@link Integer#MAX_VALUE}, because those floats themselves will lose precision at that scale). This 852 * is closely related to {@link #sway(float)}, but the shape of the output when graphed is almost identical to 853 * sin(). The difference between the result of this method and {@link Math#sin(double)} should be under 0.0011 at 854 * all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for 855 * potentially higher errors, though. 856 * <br> 857 * The error for this float version is extremely close to the double version, {@link #sin(double)}, so you should 858 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 859 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 860 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 861 * and likewise for doubles. 862 * <br> 863 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 864 * by a measurable amount. 865 * <br> 866 * The technique for sine approximation is mostly from 867 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 868 * with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range. 869 * @param radians an angle in radians as a float, often from 0 to pi * 2, though not required to be. 870 * @return the sine of the given angle, as a float between -1f and 1f (both inclusive) 871 */ 872 public static float sin(float radians) 873 { 874 radians *= 0.6366197723675814f; 875 final int floor = (radians >= 0.0 ? (int) radians : (int) radians - 1) & -2; 876 radians -= floor; 877 radians *= 2f - radians; 878 return radians * (-0.775f - 0.225f * radians) * ((floor & 2) - 1); 879 } 880 881 /** 882 * A fairly-close approximation of {@link Math#cos(double)} that can be significantly faster (between 8x and 80x 883 * faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX you should 884 * consider its more-precise and sometimes-faster MathUtils.cos() method. Because this method doesn't rely on a 885 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 886 * with this method than with MathUtils. Takes the same arguments Math.cos() does, so one angle in radians, 887 * which may technically be any float (but this will lose precision on fairly large floats, such as those that are 888 * larger than {@link Integer#MAX_VALUE}, because those floats themselves will lose precision at that scale). This 889 * is closely related to {@link #sway(float)}, but the shape of the output when graphed is almost identical to 890 * cos(). The difference between the result of this method and {@link Math#cos(double)} should be under 0.0011 at 891 * all points between -pi and pi, with an average difference of about 0.0005; not all points have been checked for 892 * potentially higher errors, though. 893 * <br> 894 * The error for this float version is extremely close to the double version, {@link #cos(double)}, so you should 895 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 896 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 897 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 898 * and likewise for doubles. 899 * <br> 900 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 901 * by a measurable amount. 902 * <br> 903 * The technique for cosine approximation is mostly from 904 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 905 * with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range. 906 * @param radians an angle in radians as a float, often from 0 to pi * 2, though not required to be. 907 * @return the cosine of the given angle, as a float between -1f and 1f (both inclusive) 908 */ 909 public static float cos(float radians) 910 { 911 radians = radians * 0.6366197723675814f + 1f; 912 final int floor = (radians >= 0.0 ? (int) radians : (int) radians - 1) & -2; 913 radians -= floor; 914 radians *= 2f - radians; 915 return radians * (-0.775f - 0.225f * radians) * ((floor & 2) - 1); 916 } 917 /** 918 * A fairly-close approximation of {@link Math#sin(double)} that can be significantly faster (between 8x and 80x 919 * faster sin() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should 920 * consider its more-precise and sometimes-faster MathUtils.sinDeg() method. Because this method doesn't rely on a 921 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 922 * with this method than with MathUtils. Takes one angle in degrees, 923 * which may technically be any float (but this will lose precision on fairly large floats, such as those that are 924 * larger than {@link Integer#MAX_VALUE}, because those floats themselves will lose precision at that scale). This 925 * is closely related to {@link #sway(float)}, but the shape of the output when graphed is almost identical to 926 * sin(). The difference between the result of this method and {@link Math#sin(double)} should be under 0.0011 at 927 * all points between -360 and 360, with an average difference of about 0.0005; not all points have been checked for 928 * potentially higher errors, though. 929 * <br> 930 * The error for this float version is extremely close to the double version, {@link #sin(double)}, so you should 931 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 932 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 933 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 934 * and likewise for doubles. 935 * <br> 936 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 937 * by a measurable amount. 938 * <br> 939 * The technique for sine approximation is mostly from 940 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 941 * with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range. 942 * @param degrees an angle in degrees as a float, often from 0 to 360, though not required to be. 943 * @return the sine of the given angle, as a float between -1f and 1f (both inclusive) 944 */ 945 public static float sinDegrees(float degrees) 946 { 947 degrees = degrees * 0.011111111111111112f; 948 final int floor = (degrees >= 0.0 ? (int) degrees : (int) degrees - 1) & -2; 949 degrees -= floor; 950 degrees *= 2f - degrees; 951 return degrees * (-0.775f - 0.225f * degrees) * ((floor & 2) - 1); 952 } 953 954 /** 955 * A fairly-close approximation of {@link Math#cos(double)} that can be significantly faster (between 8x and 80x 956 * faster cos() calls in benchmarking, and both takes and returns floats; if you have access to libGDX, you should 957 * consider its more-precise and sometimes-faster MathUtils.cosDeg() method. Because this method doesn't rely on a 958 * lookup table, where libGDX's MathUtils does, applications that have a bottleneck on memory may perform better 959 * with this method than with MathUtils. Takes one angle in degrees, 960 * which may technically be any float (but this will lose precision on fairly large floats, such as those that are 961 * larger than {@link Integer#MAX_VALUE}, because those floats themselves will lose precision at that scale). This 962 * is closely related to {@link #sway(float)}, but the shape of the output when graphed is almost identical to 963 * cos(). The difference between the result of this method and {@link Math#cos(double)} should be under 0.0011 at 964 * all points between -360 and 360, with an average difference of about 0.0005; not all points have been checked for 965 * potentially higher errors, though. 966 * <br> 967 * The error for this float version is extremely close to the double version, {@link #cos(double)}, so you should 968 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 969 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 970 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 971 * and likewise for doubles. 972 * <br> 973 * Unlike in previous versions of this method, the sign of the input doesn't affect performance here, at least not 974 * by a measurable amount. 975 * <br> 976 * The technique for cosine approximation is mostly from 977 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 978 * with credit to "Nick". Changes have been made to accelerate wrapping from any float to the valid input range. 979 * @param degrees an angle in degrees as a float, often from 0 to pi * 2, though not required to be. 980 * @return the cosine of the given angle, as a float between -1f and 1f (both inclusive) 981 */ 982 public static float cosDegrees(float degrees) 983 { 984 degrees = degrees * 0.011111111111111112f + 1f; 985 final int floor = (degrees >= 0.0 ? (int) degrees : (int) degrees - 1) & -2; 986 degrees -= floor; 987 degrees *= 2f - degrees; 988 return degrees * (-0.775f - 0.225f * degrees) * ((floor & 2) - 1); 989 } 990 991 /** 992 * A variation on {@link Math#sin(double)} that takes its input as a fraction of a turn instead of in radians; one 993 * turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; 994 * to make a sine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide 995 * the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also 996 * called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before 997 * passing that value here. The brad case is especially useful because you can use a byte for any brad values, and 998 * adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the 999 * results (you still divide by 256.0 when you pass the brad value to this method). 1000 * <br> 1001 * The error for this double version is extremely close to the float version, {@link #sin_(float)}, so you should 1002 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 1003 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 1004 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 1005 * and likewise for doubles. 1006 * <br> 1007 * The technique for sine approximation is mostly from 1008 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 1009 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 1010 * @param turns an angle as a fraction of a turn as a double, with 0.5 here equivalent to PI radians in {@link #cos(double)} 1011 * @return the sine of the given angle, as a double between -1.0 and 1.0 (both inclusive) 1012 */ 1013 public static double sin_(double turns) 1014 { 1015 turns *= 4.0; 1016 final long floor = (turns >= 0.0 ? (long) turns : (long) turns - 1L) & -2L; 1017 turns -= floor; 1018 turns *= 2.0 - turns; 1019 return turns * (-0.775 - 0.225 * turns) * ((floor & 2L) - 1L); 1020 } 1021 1022 /** 1023 * A variation on {@link Math#cos(double)} that takes its input as a fraction of a turn instead of in radians; one 1024 * turn is equal to 360 degrees or two*PI radians. This can be useful as a building block for other measurements; 1025 * to make a cosine method that takes its input in grad (with 400 grad equal to 360 degrees), you would just divide 1026 * the grad value by 400.0 (or multiply it by 0.0025) and pass it to this method. Similarly for binary degrees, also 1027 * called brad (with 256 brad equal to 360 degrees), you would divide by 256.0 or multiply by 0.00390625 before 1028 * passing that value here. The brad case is especially useful because you can use a byte for any brad values, and 1029 * adding up those brad values will wrap correctly (256 brad goes back to 0) while keeping perfect precision for the 1030 * results (you still divide by 256.0 when you pass the brad value to this method). 1031 * <br> 1032 * The error for this double version is extremely close to the float version, {@link #cos_(float)}, so you should 1033 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 1034 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 1035 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 1036 * and likewise for doubles. 1037 * <br> 1038 * The technique for cosine approximation is mostly from 1039 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 1040 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 1041 * @param turns an angle as a fraction of a turn as a double, with 0.5 here equivalent to PI radians in {@link #cos(double)} 1042 * @return the cosine of the given angle, as a double between -1.0 and 1.0 (both inclusive) 1043 */ 1044 public static double cos_(double turns) 1045 { 1046 turns = turns * 4.0 + 1.0; 1047 final long floor = (turns >= 0.0 ? (long) turns : (long) turns - 1L) & -2L; 1048 turns -= floor; 1049 turns *= 2.0 - turns; 1050 return turns * (-0.775 - 0.225 * turns) * ((floor & 2L) - 1L); 1051 } 1052 1053 /** 1054 * A variation on {@link Math#sin(double)} that takes its input as a fraction of a turn instead of in radians (it 1055 * also takes and returns a float); one turn is equal to 360 degrees or two*PI radians. This can be useful as a 1056 * building block for other measurements; to make a sine method that takes its input in grad (with 400 grad equal to 1057 * 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this 1058 * method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 1059 * 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you 1060 * can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) 1061 * while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this 1062 * method). 1063 * <br> 1064 * The error for this float version is extremely close to the double version, {@link #sin_(double)}, so you should 1065 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 1066 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 1067 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 1068 * and likewise for doubles. 1069 * <br> 1070 * The technique for sine approximation is mostly from 1071 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 1072 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 1073 * @param turns an angle as a fraction of a turn as a float, with 0.5 here equivalent to PI radians in {@link #cos(double)} 1074 * @return the sine of the given angle, as a float between -1.0 and 1.0 (both inclusive) 1075 */ 1076 public static float sin_(float turns) 1077 { 1078 turns *= 4f; 1079 final long floor = (turns >= 0.0 ? (long) turns : (long) turns - 1L) & -2L; 1080 turns -= floor; 1081 turns *= 2f - turns; 1082 return turns * (-0.775f - 0.225f * turns) * ((floor & 2L) - 1L); 1083 } 1084 1085 /** 1086 * A variation on {@link Math#cos(double)} that takes its input as a fraction of a turn instead of in radians (it 1087 * also takes and returns a float); one turn is equal to 360 degrees or two*PI radians. This can be useful as a 1088 * building block for other measurements; to make a cosine method that takes its input in grad (with 400 grad equal 1089 * to 360 degrees), you would just divide the grad value by 400.0 (or multiply it by 0.0025) and pass it to this 1090 * method. Similarly for binary degrees, also called brad (with 256 brad equal to 360 degrees), you would divide by 1091 * 256.0 or multiply by 0.00390625 before passing that value here. The brad case is especially useful because you 1092 * can use a byte for any brad values, and adding up those brad values will wrap correctly (256 brad goes back to 0) 1093 * while keeping perfect precision for the results (you still divide by 256.0 when you pass the brad value to this 1094 * method). 1095 * <br> 1096 * The error for this float version is extremely close to the float version, {@link #cos_(double)}, so you should 1097 * choose based on what type you have as input and/or want to return rather than on quality concerns. Coercion 1098 * between float and double takes about as long as this method normally takes to run (or longer), so if you have 1099 * floats you should usually use methods that take floats (or return floats, if assigning the result to a float), 1100 * and likewise for doubles. 1101 * <br> 1102 * The technique for cosine approximation is mostly from 1103 * <a href="https://web.archive.org/web/20080228213915/http://devmaster.net/forums/showthread.php?t=5784">this archived DevMaster thread</a>, 1104 * with credit to "Nick". Changes have been made to accelerate wrapping from any double to the valid input range. 1105 * @param turns an angle as a fraction of a turn as a float, with 0.5 here equivalent to PI radians in {@link #cos(double)} 1106 * @return the cosine of the given angle, as a float between -1.0 and 1.0 (both inclusive) 1107 */ 1108 public static float cos_(float turns) 1109 { 1110 turns = turns * 4f + 1f; 1111 final long floor = (turns >= 0.0 ? (long) turns : (long) turns - 1L) & -2L; 1112 turns -= floor; 1113 turns *= 2f - turns; 1114 return turns * (-0.775f - 0.225f * turns) * ((floor & 2L) - 1L); 1115 } 1116 1117 /** 1118 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1119 * approximation. Maximum error is below 0.001 radians. 1120 * Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in radians. 1121 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1122 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1123 * MathUtils approximation of the same method; MathUtils seems to have worse average error, though. 1124 * Credit to StackExchange user njuffa, who gave 1125 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. This method changed from an earlier 1126 * technique that was twice as fast but had very poor quality, enough to be visually noticeable. See also 1127 * {@link #atan2_(double, double)} if you don't want a mess converting to degrees or some other measurement, since 1128 * that method returns an angle from 0.0 (equal to 0 degrees) to 1.0 (equal to 360 degrees). 1129 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1130 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1131 * @return the angle to the given point, in radians as a double 1132 */ 1133 public static double atan2(final double y, final double x) 1134 { 1135 /* 1136a := min (|x|, |y|) / max (|x|, |y|) 1137s := a * a 1138r := ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a 1139if |y| > |x| then r := 1.57079637 - r 1140if x < 0 then r := 3.14159274 - r 1141if y < 0 then r := -r 1142 */ 1143 if(y == 0.0 && x >= 0.0) return 0.0; 1144 final double ax = Math.abs(x), ay = Math.abs(y); 1145 if(ax < ay) 1146 { 1147 final double a = ax / ay, s = a * a, 1148 r = 1.57079637 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1149 return (x < 0.0) ? (y < 0.0) ? -3.14159274 + r : 3.14159274 - r : (y < 0.0) ? -r : r; 1150 } 1151 else { 1152 final double a = ay / ax, s = a * a, 1153 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1154 return (x < 0.0) ? (y < 0.0) ? -3.14159274 + r : 3.14159274 - r : (y < 0.0) ? -r : r; 1155 } 1156 } 1157 1158 /** 1159 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1160 * approximation. Maximum error is below 0.001 radians. 1161 * Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in radians. 1162 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1163 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1164 * MathUtils approximation of the same method; MathUtils seems to have worse average error, though. 1165 * Credit to StackExchange user njuffa, who gave 1166 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. This method changed from an earlier 1167 * technique that was twice as fast but had very poor quality, enough to be visually noticeable. See also 1168 * {@link #atan2_(float, float)} if you don't want a mess converting to degrees or some other measurement, since 1169 * that method returns an angle from 0f (equal to 0 degrees) to 1f (equal to 360 degrees). 1170 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1171 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1172 * @return the angle to the given point, in radians as a float 1173 */ 1174 public static float atan2(final float y, final float x) 1175 { 1176 /* 1177a := min (|x|, |y|) / max (|x|, |y|) 1178s := a * a 1179r := ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a 1180if |y| > |x| then r := 1.57079637 - r 1181if x < 0 then r := 3.14159274 - r 1182if y < 0 then r := -r 1183 */ 1184 if(y == 0f && x >= 0f) return 0f; 1185 final float ax = Math.abs(x), ay = Math.abs(y); 1186 if(ax < ay) 1187 { 1188 final float a = ax / ay, s = a * a, 1189 r = 1.57079637f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1190 return (x < 0f) ? (y < 0f) ? -3.14159274f + r : 3.14159274f - r : (y < 0f) ? -r : r; 1191 } 1192 else { 1193 final float a = ay / ax, s = a * a, 1194 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1195 return (x < 0f) ? (y < 0f) ? -3.14159274f + r : 3.14159274f - r : (y < 0f) ? -r : r; 1196 } 1197 } 1198 1199 /** 1200 * Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as 1201 * doubles and returning an angle measured in turns from 0.0 to 1.0 (inclusive), with one cycle over the range 1202 * equivalent to 360 degrees or 2PI radians. You can multiply the angle by {@code 6.2831855f} to change to radians, 1203 * or by {@code 360f} to change to degrees. Takes y and x (in that unusual order) as doubles. Will never return a 1204 * negative number, which may help avoid costly floating-point modulus when you actually want a positive number. 1205 * Credit to StackExchange user njuffa, who gave 1206 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. Note that 1207 * {@link #atan2(double, double)} returns an angle in radians and can return negative results, which may be fine for 1208 * many tasks; these two methods are extremely close in implementation and speed. 1209 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1210 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1211 * @return the angle to the given point, as a double from 0.0 to 1.0, inclusive 1212 */ 1213 public static double atan2_(final double y, final double x) 1214 { 1215 if(y == 0.0 && x >= 0.0) return 0.0; 1216 final double ax = Math.abs(x), ay = Math.abs(y); 1217 if(ax < ay) 1218 { 1219 final double a = ax / ay, s = a * a, 1220 r = 0.25 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1221 return (x < 0.0) ? (y < 0.0) ? 0.5 + r : 0.5 - r : (y < 0.0) ? 1.0 - r : r; 1222 } 1223 else { 1224 final double a = ay / ax, s = a * a, 1225 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1226 return (x < 0.0) ? (y < 0.0) ? 0.5 + r : 0.5 - r : (y < 0.0) ? 1.0 - r : r; 1227 } 1228 } 1229 /** 1230 * Altered-range approximation of the frequently-used trigonometric method atan2, taking y and x positions as floats 1231 * and returning an angle measured in turns from 0.0f to 1.0f, with one cycle over the range equivalent to 360 1232 * degrees or 2PI radians. You can multiply the angle by {@code 6.2831855f} to change to radians, or by {@code 360f} 1233 * to change to degrees. Takes y and x (in that unusual order) as floats. Will never return a negative number, which 1234 * may help avoid costly floating-point modulus when you actually want a positive number. 1235 * Credit to StackExchange user njuffa, who gave 1236 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. Note that 1237 * {@link #atan2(float, float)} returns an angle in radians and can return negative results, which may be fine for 1238 * many tasks; these two methods are extremely close in implementation and speed. 1239 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1240 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1241 * @return the angle to the given point, as a float from 0.0f to 1.0f, inclusive 1242 */ 1243 public static float atan2_(final float y, final float x) 1244 { 1245 if(y == 0.0 && x >= 0.0) return 0f; 1246 final float ax = Math.abs(x), ay = Math.abs(y); 1247 if(ax < ay) 1248 { 1249 final float a = ax / ay, s = a * a, 1250 r = 0.25f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1251 return (x < 0.0f) ? (y < 0.0f) ? 0.5f + r : 0.5f - r : (y < 0.0f) ? 1f - r : r; 1252 } 1253 else { 1254 final float a = ay / ax, s = a * a, 1255 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1256 return (x < 0.0f) ? (y < 0.0f) ? 0.5f + r : 0.5f - r : (y < 0.0f) ? 1f - r : r; 1257 } 1258 } 1259 1260 /** 1261 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1262 * approximation, and giving a result in degrees from -180 to 180. Maximum error is below 0.1 degrees. 1263 * Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in degrees. 1264 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1265 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1266 * MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. 1267 * Credit to StackExchange user njuffa, who gave 1268 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. 1269 * <br> 1270 * See also {@link #atan2Degrees360(double, double)}, which is just like this but returns an angle from 0 to 360, 1271 * instead of -180 to 180, in case negative angles are undesirable. 1272 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1273 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1274 * @return the angle to the given point, in degrees as a double 1275 */ 1276 public static double atan2Degrees(final double y, final double x) 1277 { 1278 if(y == 0.0 && x >= 0.0) return 0.0; 1279 final double ax = Math.abs(x), ay = Math.abs(y); 1280 if(ax < ay) 1281 { 1282 final double a = ax / ay, s = a * a, 1283 r = 90.0 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 57.29577951308232; 1284 return (x < 0.0) ? (y < 0.0) ? -180.0 + r : 180.0 - r : (y < 0.0) ? -r : r; 1285 } 1286 else { 1287 final double a = ay / ax, s = a * a, 1288 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 57.29577951308232; 1289 return (x < 0.0) ? (y < 0.0) ? -180.0 + r : 180.0 - r : (y < 0.0) ? -r : r; 1290 } 1291 } 1292 1293 /** 1294 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1295 * approximation, and giving a result in degrees from -180 to 180. Maximum error is below 0.1 degrees. 1296 * Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees. 1297 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1298 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1299 * MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. 1300 * Credit to StackExchange user njuffa, who gave 1301 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. 1302 * <br> 1303 * See also {@link #atan2Degrees360(float, float)}, which is just like this but returns an angle from 0 to 360, 1304 * instead of -180 to 180, in case negative angles are undesirable. 1305 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1306 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1307 * @return the angle to the given point, in degrees as a float 1308 */ 1309 public static float atan2Degrees(final float y, final float x) 1310 { 1311 if(y == 0f && x >= 0f) return 0f; 1312 final float ax = Math.abs(x), ay = Math.abs(y); 1313 if(ax < ay) 1314 { 1315 final float a = ax / ay, s = a * a, 1316 r = 90f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 57.29577951308232f; 1317 return (x < 0f) ? (y < 0f) ? -180f + r : 180f - r : (y < 0f) ? -r : r; 1318 } 1319 else { 1320 final float a = ay / ax, s = a * a, 1321 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 57.29577951308232f; 1322 return (x < 0f) ? (y < 0f) ? -180f + r : 180f - r : (y < 0f) ? -r : r; 1323 } 1324 } 1325 1326 /** 1327 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1328 * approximation, and giving a result in degrees from 0 to 360. Maximum error is below 0.1 degrees. 1329 * Takes y and x (in that unusual order) as doubles, and returns the angle from the origin to that point in degrees. 1330 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1331 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1332 * MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. 1333 * Credit to StackExchange user njuffa, who gave 1334 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. 1335 * <br> 1336 * See also {@link #atan2Degrees(double, double)}, which is just like this but returns an angle from -180 to 180, 1337 * matching {@link Math#atan2(double, double)}'s convention. 1338 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1339 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1340 * @return the angle to the given point, in degrees as a double 1341 */ 1342 public static double atan2Degrees360(final double y, final double x) 1343 { 1344 if(y == 0.0 && x >= 0.0) return 0.0; 1345 final double ax = Math.abs(x), ay = Math.abs(y); 1346 if(ax < ay) 1347 { 1348 final double a = ax / ay, s = a * a, 1349 r = 90.0 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 57.29577951308232; 1350 return (x < 0.0) ? (y < 0.0) ? 180.0 + r : 180.0 - r : (y < 0.0) ? 360.0 - r : r; 1351 } 1352 else { 1353 final double a = ay / ax, s = a * a, 1354 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 57.29577951308232; 1355 return (x < 0.0) ? (y < 0.0) ? 180.0 + r : 180.0 - r : (y < 0.0) ? 360.0 - r : r; 1356 } 1357 } 1358 /** 1359 * Close approximation of the frequently-used trigonometric method atan2, with higher precision than LibGDX's atan2 1360 * approximation, and giving a result in degrees from 0 to 360. Maximum error is below 0.1 degrees. 1361 * Takes y and x (in that unusual order) as floats, and returns the angle from the origin to that point in degrees. 1362 * It is about 5 times faster than {@link Math#atan2(double, double)} (roughly 17 ns instead of roughly 88 ns for 1363 * Math, though the computer was under some load during testing). It is almost identical in speed to LibGDX' 1364 * MathUtils approximation after converting to degrees; MathUtils seems to have worse average error, though. 1365 * Credit to StackExchange user njuffa, who gave 1366 * <a href="https://math.stackexchange.com/a/1105038">this useful answer</a>. 1367 * <br> 1368 * See also {@link #atan2Degrees(float, float)}, which is just like this but returns an angle from -180 to 180, 1369 * matching {@link Math#atan2(double, double)}'s convention. 1370 * @param y y-component of the point to find the angle towards; note the parameter order is unusual by convention 1371 * @param x x-component of the point to find the angle towards; note the parameter order is unusual by convention 1372 * @return the angle to the given point, in degrees as a float 1373 */ 1374 public static float atan2Degrees360(final float y, final float x) 1375 { 1376 if(y == 0.0 && x >= 0.0) return 0f; 1377 final float ax = Math.abs(x), ay = Math.abs(y); 1378 if(ax < ay) 1379 { 1380 final float a = ax / ay, s = a * a, 1381 r = 90f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 57.29577951308232f; 1382 return (x < 0f) ? (y < 0f) ? 180f + r : 180f - r : (y < 0f) ? 360f - r : r; 1383 } 1384 else { 1385 final float a = ay / ax, s = a * a, 1386 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 57.29577951308232f; 1387 return (x < 0f) ? (y < 0f) ? 180f + r : 180f - r : (y < 0f) ? 360f - r : r; 1388 } 1389 } 1390 1391 1392 // /** 1393// * Arc sine approximation with fairly low error while still being faster than {@link NumberTools#sin(double)}. 1394// * This formula is number 201 in <a href=">http://www.fastcode.dk/fastcodeproject/articles/index.htm">Dennis 1395// * Kjaer Christensen's unfinished math work on arc sine approximation</a>. This method is about 40 times faster 1396// * than {@link Math#asin(double)}. Fast but imprecise. 1397// * @param a an input to the inverse sine function, from -1 to 1 inclusive (error is higher approaching -1 or 1) 1398// * @return an output from the inverse sine function, from -PI/2 to PI/2 inclusive. 1399// */ 1400// public static double asin(double a) { 1401// return (a * (1.0 + (a *= a) * (-0.141514171442891431 + a * -0.719110791477959357))) / 1402// (1.0 + a * (-0.439110389941411144 + a * -0.471306172023844527)); 1403// } 1404// /** 1405// * Arc sine approximation with fairly low error while still being faster than {@link NumberTools#sin(float)}. 1406// * This formula is number 201 in <a href=">http://www.fastcode.dk/fastcodeproject/articles/index.htm">Dennis 1407// * Kjaer Christensen's unfinished math work on arc sine approximation</a>. This method is about 40 times faster 1408// * than {@link Math#asin(double)}, and takes and returns a float. Fast but imprecise. 1409// * @param a an input to the inverse sine function, from -1 to 1 inclusive (error is higher approaching -1 or 1) 1410// * @return an output from the inverse sine function, from -PI/2 to PI/2 inclusive. 1411// */ 1412// public static float asin(float a) { 1413// return (a * (1f + (a *= a) * (-0.141514171442891431f + a * -0.719110791477959357f))) / 1414// (1f + a * (-0.439110389941411144f + a * -0.471306172023844527f)); 1415// } 1416 /** 1417 * Arc sine approximation with very low error, based on a simplified version of {@link #atan2(double, double)}. 1418 * This method is usually much faster than {@link Math#asin(double)}, but is somewhat less precise than Math's 1419 * implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't 1420 * quite as fast; the difference in precision is hard to spot but can be noticeable in some usage. 1421 * @param n an input to the inverse sine function, from -1 to 1 inclusive 1422 * @return an output from the inverse sine function, from PI/-2.0 to PI/2.0 inclusive. 1423 */ 1424 public static float asin(final float n) 1425 { 1426 final float ax = (float) Math.sqrt(1f - n * n), ay = Math.abs(n); 1427 if(ax < ay) 1428 { 1429 final float a = ax / ay, s = a * a, 1430 r = 1.57079637f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1431 return (n < 0f) ? -r : r; 1432 } 1433 else { 1434 final float a = ay / ax, s = a * a, 1435 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1436 return (n < 0f) ? -r : r; 1437 } 1438 } 1439 1440// /** 1441// * Arc cosine approximation with fairly low error while still being faster than {@link NumberTools#cos(double)}. 1442// * This formula is number 201 in <a href=">http://www.fastcode.dk/fastcodeproject/articles/index.htm">Dennis 1443// * Kjaer Christensen's unfinished math work on arc sine approximation</a>, with a basic change to go from arc sine 1444// * to arc cosine. This method is faster than {@link Math#acos(double)}. Fast but imprecise. 1445// * @param a an input to the inverse cosine function, from -1 to 1 inclusive (error is higher approaching -1 or 1) 1446// * @return an output from the inverse cosine function, from 0 to PI inclusive. 1447// */ 1448// public static double acos(double a) { 1449// return 1.5707963267948966 - (a * (1.0 + (a *= a) * (-0.141514171442891431 + a * -0.719110791477959357))) / 1450// (1.0 + a * (-0.439110389941411144 + a * -0.471306172023844527)); 1451// } 1452 1453 /** 1454 * Arc sine approximation with very low error, based on a simplified version of {@link #atan2(float, float)}. 1455 * This method is usually much faster than {@link Math#asin(double)}, but is somewhat less precise than Math's 1456 * implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't 1457 * quite as fast; the difference in precision is hard to spot but can be noticeable in some usage. 1458 * @param n an input to the inverse sine function, from -1 to 1 inclusive 1459 * @return an output from the inverse sine function, from PI/-2.0 to PI/2.0 inclusive. 1460 */ 1461 public static double asin(final double n) 1462 { 1463 final double ax = Math.sqrt(1.0 - n * n), ay = Math.abs(n); 1464 if(ax < ay) 1465 { 1466 final double a = ax / ay, s = a * a, 1467 r = 1.57079637 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1468 return (n < 0.0) ? -r : r; 1469 } 1470 else { 1471 final double a = ay / ax, s = a * a, 1472 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1473 return (n < 0.0) ? -r : r; 1474 } 1475 } 1476 /** 1477 * Arc cosine approximation with very low error, based on a simplified version of {@link #atan2(double, double)}. 1478 * This method is usually much faster than {@link Math#acos(double)}, but is somewhat less precise than Math's 1479 * implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't 1480 * quite as fast; the difference in precision is hard to spot but can be noticeable in some usage. 1481 * @param n an input to the inverse cosine function, from -1 to 1 inclusive 1482 * @return an output from the inverse cosine function, from 0 to PI inclusive. 1483 */ 1484 public static double acos(final double n) 1485 { 1486 final double ax = Math.abs(n), ay = Math.sqrt(1.0 - n * n); 1487 if(ax < ay) 1488 { 1489 final double a = ax / ay, s = a * a, 1490 r = 1.57079637 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1491 return (n < 0.0) ? Math.PI - r : r; 1492 } 1493 else { 1494 final double a = ay / ax, s = a * a, 1495 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a); 1496 return (n < 0.0) ? Math.PI - r : r; 1497 } 1498 } 1499// 1500// /** 1501// * Arc cosine approximation with fairly low error while still being faster than {@link NumberTools#cos(float)}. 1502// * This formula is number 201 in <a href=">http://www.fastcode.dk/fastcodeproject/articles/index.htm">Dennis 1503// * Kjaer Christensen's unfinished math work on arc sine approximation</a>, with a basic change to go from arc sine 1504// * to arc cosine. This method is faster than {@link Math#acos(double)}, and takes and returns a float. Fast but 1505// * imprecise. 1506// * @param a an input to the inverse cosine function, from -1 to 1 inclusive (error is higher approaching -1 or 1) 1507// * @return an output from the inverse cosine function, from 0 to PI inclusive. 1508// */ 1509// public static float acos(float a) { 1510// return 1.5707963267948966f - (a * (1f + (a *= a) * (-0.141514171442891431f + a * -0.719110791477959357f))) / 1511// (1f + a * (-0.439110389941411144f + a * -0.471306172023844527f)); 1512// } 1513// 1514 /** 1515 * Arc cosine approximation with very low error, based on a simplified version of {@link #atan2(float, float)}. 1516 * This method is usually much faster than {@link Math#acos(double)}, but is somewhat less precise than Math's 1517 * implementation). It is currently more precise than libGDX's approximation in their MathUtils, but this isn't 1518 * quite as fast; the difference in precision is hard to spot but can be noticeable in some usage. 1519 * @param n an input to the inverse cosine function, from -1 to 1 inclusive 1520 * @return an output from the inverse cosine function, from 0 to PI inclusive. 1521 */ 1522 public static float acos(final float n) 1523 { 1524 final float ax = Math.abs(n), ay = (float) Math.sqrt(1f - n * n); 1525 if(ax < ay) 1526 { 1527 final float a = ax / ay, s = a * a, 1528 r = 1.57079637f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1529 return (n < 0f) ? 3.14159265358979323846f - r : r; 1530 } 1531 else { 1532 final float a = ay / ax, s = a * a, 1533 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a); 1534 return (n < 0.0) ? 3.14159265358979323846f - r : r; 1535 } 1536 } 1537 1538 /** 1539 * Inverse sine function (arcsine) but with output measured in turns instead of radians. Possible results for this 1540 * range from 0.75 (inclusive) to 1.0 (exclusive), and continuing past that to 0.0 (inclusive) to 0.25 (inclusive). 1541 * <br> 1542 * This method is extremely similar to the non-turn approximation. 1543 * @param n a double from -1.0 to 1.0 (both inclusive), usually the output of sin_() or cos_() 1544 * @return one of the values that would produce {@code n} if it were passed to {@link #sin_(double)} 1545 */ 1546 public static double asin_(final double n) 1547 { 1548 if(n == 0.0) return 0.0; 1549 final double ax = Math.sqrt(1.0 - n * n), ay = Math.abs(n); 1550 if(ax < ay) 1551 { 1552 final double a = ax / ay, s = a * a, 1553 r = 0.25 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1554 return (n < 0.0) ? 1.0 - r : r; 1555 } 1556 else { 1557 final double a = ay / ax, s = a * a, 1558 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1559 return (n < 0.0) ? 1.0 - r : r; 1560 } 1561 } 1562 /** 1563 * Inverse cosine function (arccos) but with output measured in turns instead of radians. Possible results for this 1564 * range from 0.0 (inclusive) to 0.5 (inclusive). 1565 * <br> 1566 * This method is extremely similar to the non-turn approximation. 1567 * @param n a double from -1.0 to 1.0 (both inclusive), usually the output of sin_() or cos_() 1568 * @return one of the values that would produce {@code n} if it were passed to {@link #cos_(double)} 1569 */ 1570 public static double acos_(final double n) 1571 { 1572 final double ax = Math.abs(n), ay = Math.sqrt(1.0 - n * n); 1573 if(ax < ay) 1574 { 1575 final double a = ax / ay, s = a * a, 1576 r = 0.25 - (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1577 return (n < 0.0) ? 0.5 - r : r; 1578 } 1579 else { 1580 final double a = ay / ax, s = a * a, 1581 r = (((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a) * 0.15915494309189535; 1582 return (n < 0.0) ? 0.5 - r : r; 1583 } 1584 } 1585 1586 1587 /** 1588 * Inverse sine function (arcsine) but with output measured in turns instead of radians. Possible results for this 1589 * range from 0.75f (inclusive) to 1.0f (exclusive), and continuing past that to 0.0f (inclusive) to 0.25f 1590 * (inclusive). 1591 * <br> 1592 * This method is extremely similar to the non-turn approximation. 1593 * @param n a float from -1.0f to 1.0f (both inclusive), usually the output of sin_() or cos_() 1594 * @return one of the values that would produce {@code n} if it were passed to {@link #sin_(float)} 1595 */ 1596 public static float asin_(final float n) 1597 { 1598 if(n == 0.0f) return 0.0f; 1599 final float ax = (float) Math.sqrt(1f - n * n), ay = Math.abs(n); 1600 if(ax < ay) 1601 { 1602 final float a = ax / ay, s = a * a, 1603 r = 0.25f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1604 return (n < 0.0f) ? 1.0f - r : r; 1605 } 1606 else { 1607 final float a = ay / ax, s = a * a, 1608 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1609 return (n < 0.0f) ? 1.0f - r : r; 1610 } 1611 } 1612 /** 1613 * Inverse cosine function (arccos) but with output measured in turns instead of radians. Possible results for this 1614 * range from 0.0f (inclusive) to 0.5f (inclusive). 1615 * <br> 1616 * This method is extremely similar to the non-turn approximation. 1617 * @param n a float from -1.0f to 1.0f (both inclusive), usually the output of sin_() or cos_() 1618 * @return one of the values that would produce {@code n} if it were passed to {@link #cos_(float)} 1619 */ 1620 public static float acos_(final float n) 1621 { 1622 final float ax = Math.abs(n), ay = (float) Math.sqrt(1f - n * n); 1623 if(ax < ay) 1624 { 1625 final float a = ax / ay, s = a * a, 1626 r = 0.25f - (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1627 return (n < 0.0f) ? 0.5f - r : r; 1628 } 1629 else { 1630 final float a = ay / ax, s = a * a, 1631 r = (((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a) * 0.15915494309189535f; 1632 return (n < 0.0f) ? 0.5f - r : r; 1633 } 1634 } 1635}