| 396 | } |
| 397 | |
| 398 | float Terathon::Arctan(float x) |
| 399 | { |
| 400 | // Values of arctan(n / 64) for integers n in the range [0, 64]. |
| 401 | |
| 402 | alignas(64) static const uint32 table[65] = |
| 403 | { |
| 404 | 0x00000000, 0x3C7FFAAB, 0x3CFFEAAE, 0x3D3FDC0C, 0x3D7FAADE, 0x3D9FACF8, 0x3DBF70C1, 0x3DDF1CF6, |
| 405 | 0x3DFEADD5, 0x3E0F0FD8, 0x3E1EB777, 0x3E2E4C09, 0x3E3DCBDA, 0x3E4D3547, 0x3E5C86BB, 0x3E6BBEAF, |
| 406 | 0x3E7ADBB0, 0x3E84EE2D, 0x3E8C5FAD, 0x3E93C1B9, 0x3E9B13BA, 0x3EA25522, 0x3EA9856D, 0x3EB0A420, |
| 407 | 0x3EB7B0CA, 0x3EBEAB02, 0x3EC5926A, 0x3ECC66AA, 0x3ED32776, 0x3ED9D489, 0x3EE06DA6, 0x3EE6F29A, |
| 408 | 0x3EED6338, 0x3EF3BF5C, 0x3EFA06E8, 0x3F001CE4, 0x3F032BF5, 0x3F0630A3, 0x3F092AED, 0x3F0C1AD4, |
| 409 | 0x3F0F005D, 0x3F11DB8F, 0x3F14AC73, 0x3F177314, 0x3F1A2F81, 0x3F1CE1C9, 0x3F1F89FE, 0x3F222833, |
| 410 | 0x3F24BC7D, 0x3F2746F3, 0x3F29C7AC, 0x3F2C3EC1, 0x3F2EAC4C, 0x3F311069, 0x3F336B32, 0x3F35BCC5, |
| 411 | 0x3F38053E, 0x3F3A44BC, 0x3F3C7B5E, 0x3F3EA941, 0x3F40CE86, 0x3F42EB4B, 0x3F44FFB0, 0x3F470BD5, 0x3F490FDB |
| 412 | }; |
| 413 | |
| 414 | // arctan(a) = arctan(b) + arctan((a - b) / (ab + 1)) |
| 415 | |
| 416 | float a = Fabs(x); |
| 417 | if (a <= 1.0F) |
| 418 | { |
| 419 | float b = a * 64.0F; |
| 420 | float i = PositiveFloor(b); |
| 421 | b = i * 0.015625F; |
| 422 | |
| 423 | float arctan_b = reinterpret_cast<const float *>(table)[int32(i)]; |
| 424 | float c = (a - b) / (a * b + 1.0F); |
| 425 | float c2 = c * c; |
| 426 | |
| 427 | float arctan_c = c * (1.0F - c2 * (0.3333333333F + c2 * (0.2F - c2 * 0.1428571429F))); |
| 428 | a = arctan_b + arctan_c; |
| 429 | } |
| 430 | else |
| 431 | { |
| 432 | // arctan(a) = tau / 4 - arctan(1 / a) |
| 433 | |
| 434 | a = 1.0F / a; |
| 435 | float b = a * 64.0F; |
| 436 | float i = PositiveFloor(b); |
| 437 | b = i * 0.015625F; |
| 438 | |
| 439 | float arctan_b = reinterpret_cast<const float *>(table)[int32(i)]; |
| 440 | float c = (a - b) / (a * b + 1.0F); |
| 441 | float c2 = c * c; |
| 442 | |
| 443 | float arctan_c = c * (1.0F - c2 * (0.3333333333F + c2 * (0.2F - c2 * 0.1428571429F))); |
| 444 | a = Math::tau_over_4 - (arctan_b + arctan_c); |
| 445 | } |
| 446 | |
| 447 | return ((x < 0.0F) ? -a : a); |
| 448 | } |
| 449 | |
| 450 | float Terathon::Arctan(float y, float x) |
| 451 | { |
nothing calls this directly
no test coverage detected