Polynomials.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // Polynomials.h
  3. // cocos2d_libs
  4. //
  5. // Created by 徐俊杰 on 2020/5/21.
  6. //
  7. #ifndef Polynomials_h
  8. #define Polynomials_h
  9. #include "rparticle/Macros/RParticleMacros.h"
  10. #include "rparticle/Math/FloatConversion.h"
  11. NS_RRP_BEGIN
  12. // Returns the highest root for the cubic x^3 + px^2 + qx + r
  13. inline double CubicPolynomialRoot(const double p, const double q, const double r)
  14. {
  15. double rcp3 = 1.0/3.0;
  16. double half = 0.5;
  17. double po3 = p*rcp3;
  18. double po3_2 = po3*po3;
  19. double po3_3 = po3_2*po3;
  20. double b = po3_3 - po3*q*half + r*half;
  21. double a = -po3_2 + q*rcp3;
  22. double a3 = a*a*a;
  23. double det = a3 + b*b;
  24. if (det >= 0)
  25. {
  26. double r0 = sqrt(det) - b;
  27. r0 = r0 > 0 ? pow(r0, rcp3) : -pow(-r0, rcp3);
  28. return - po3 - a/r0 + r0;
  29. }
  30. double abs = sqrt(-a3);
  31. double arg = acos(-b/abs);
  32. abs = pow(abs, rcp3);
  33. abs = abs - a/abs;
  34. arg = -po3 + abs*cos(arg*rcp3);
  35. return arg;
  36. }
  37. // Calculates all real roots of polynomial ax^2 + bx + c (and returns how many)
  38. inline int QuadraticPolynomialRootsGeneric(const float a, const float b, const float c, float& r0, float& r1)
  39. {
  40. const float eps = 0.00001f;
  41. if (Abs(a) < eps)
  42. {
  43. if (Abs(b) > eps)
  44. {
  45. r0 = -c/b;
  46. return 1;
  47. }
  48. else
  49. return 0;
  50. }
  51. float disc = b*b - 4*a*c;
  52. if (disc < 0.0f)
  53. return 0;
  54. const float halfRcpA = 0.5f/a;
  55. const float sqrtDisc = sqrt(disc);
  56. r0 = (sqrtDisc-b)*halfRcpA;
  57. r1 = (-sqrtDisc-b)*halfRcpA;
  58. return 2;
  59. }
  60. // Calculates all the roots for the cubic ax^3 + bx^2 + cx + d. Max num roots is 3.
  61. inline int CubicPolynomialRootsGeneric(float* roots, const double a, const double b, const double c, const double d)
  62. {
  63. int numRoots = 0;
  64. if(Abs(a) >= 0.0001f)
  65. {
  66. const double p = b / a;
  67. const double q = c / a;
  68. const double r = d / a;
  69. roots[0] = CubicPolynomialRoot(p, q, r);
  70. numRoots++;
  71. double la = a;
  72. double lb = b + a * roots[0];
  73. double lc = c + b*roots[0] + a*roots[0]*roots[0];
  74. numRoots += QuadraticPolynomialRootsGeneric(la, lb, lc, roots[1], roots[2]);
  75. }
  76. else
  77. {
  78. numRoots += QuadraticPolynomialRootsGeneric(b, c, d, roots[0], roots[1]);
  79. }
  80. return numRoots;
  81. }
  82. // Specialized version of QuadraticPolynomialRootsGeneric that returns the largest root
  83. inline float QuadraticPolynomialRoot(const float a, const float b, const float c)
  84. {
  85. float r0, r1;
  86. QuadraticPolynomialRootsGeneric(a, b, c, r0, r1);
  87. return r0;
  88. }
  89. NS_RRP_END
  90. #endif /* Polynomials_h */