fast_math.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <math.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "math/fast_math.h"
  5. /**
  6. * Fast sine and cosine implementation.
  7. *
  8. * See http://lab.polygonal.de/?p=205
  9. *
  10. * @param angle
  11. * The angle in radians
  12. * WARNING: Don't use too large angles.
  13. *
  14. * @param sin
  15. * A pointer to store the sine value.
  16. *
  17. * @param cos
  18. * A pointer to store the cosine value.
  19. */
  20. void fast_sincos(float angle, float *sin, float *cos) {
  21. //always wrap input angle to -PI..PI
  22. while (angle < -M_PI) {
  23. angle += 2.0f * M_PI;
  24. }
  25. while (angle > M_PI) {
  26. angle -= 2.0f * M_PI;
  27. }
  28. //compute sine
  29. if (angle < 0.0f) {
  30. *sin = 1.27323954f * angle + 0.405284735f * angle * angle;
  31. if (*sin < 0.0f) {
  32. *sin = 0.225f * (*sin * -*sin - *sin) + *sin;
  33. } else {
  34. *sin = 0.225f * (*sin * *sin - *sin) + *sin;
  35. }
  36. } else {
  37. *sin = 1.27323954f * angle - 0.405284735f * angle * angle;
  38. if (*sin < 0.0f) {
  39. *sin = 0.225f * (*sin * -*sin - *sin) + *sin;
  40. } else {
  41. *sin = 0.225f * (*sin * *sin - *sin) + *sin;
  42. }
  43. }
  44. // compute cosine: sin(x + PI/2) = cos(x)
  45. angle += 0.5f * M_PI;
  46. if (angle > M_PI) {
  47. angle -= 2.0f * M_PI;
  48. }
  49. if (angle < 0.0f) {
  50. *cos = 1.27323954f * angle + 0.405284735f * angle * angle;
  51. if (*cos < 0.0f) {
  52. *cos = 0.225f * (*cos * -*cos - *cos) + *cos;
  53. } else {
  54. *cos = 0.225f * (*cos * *cos - *cos) + *cos;
  55. }
  56. } else {
  57. *cos = 1.27323954f * angle - 0.405284735f * angle * angle;
  58. if (*cos < 0.0f) {
  59. *cos = 0.225f * (*cos * -*cos - *cos) + *cos;
  60. } else {
  61. *cos = 0.225f * (*cos * *cos - *cos) + *cos;
  62. }
  63. }
  64. }
  65. /**
  66. * Make sure that 0 <= angle < 360
  67. *
  68. * @param angle
  69. * The angle to normalize.
  70. */
  71. void fast_norm_angle(float *angle) {
  72. *angle = fmodf(*angle, 360.0f);
  73. if (*angle < 0.0f) {
  74. *angle += 360.0f;
  75. }
  76. }
  77. void normal_sincosf(float angle, float *sin, float *cos) {
  78. *sin = sinf(angle);
  79. *cos = cosf(angle);
  80. }