IntpAkimaUniform1.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/IntpAkima1.h>
  9. namespace WwiseGTE
  10. {
  11. template <typename Real>
  12. class IntpAkimaUniform1 : public IntpAkima1<Real>
  13. {
  14. public:
  15. // Construction and destruction. The interpolator is for uniformly
  16. // spaced x-values.
  17. IntpAkimaUniform1(int quantity, Real xMin, Real xSpacing, Real const* F)
  18. :
  19. IntpAkima1<Real>(quantity, F),
  20. mXMin(xMin),
  21. mXSpacing(xSpacing)
  22. {
  23. LogAssert(mXSpacing > (Real)0, "Spacing must be positive.");
  24. mXMax = mXMin + mXSpacing * static_cast<Real>(quantity - 1);
  25. // Compute slopes.
  26. Real invDX = (Real)1 / mXSpacing;
  27. std::vector<Real> slope(quantity + 3);
  28. int i, ip1, ip2;
  29. for (i = 0, ip1 = 1, ip2 = 2; i < quantity - 1; ++i, ++ip1, ++ip2)
  30. {
  31. slope[ip2] = (this->mF[ip1] - this->mF[i]) * invDX;
  32. }
  33. slope[1] = (Real)2 * slope[2] - slope[3];
  34. slope[0] = (Real)2 * slope[1] - slope[2];
  35. slope[quantity + 1] = (Real)2 * slope[quantity] - slope[quantity - 1];
  36. slope[quantity + 2] = (Real)2 * slope[quantity + 1] - slope[quantity];
  37. // Construct derivatives.
  38. std::vector<Real> FDer(quantity);
  39. for (i = 0; i < quantity; ++i)
  40. {
  41. FDer[i] = this->ComputeDerivative(&slope[i]);
  42. }
  43. // Construct polynomials.
  44. Real invDX2 = (Real)1 / (mXSpacing * mXSpacing);
  45. Real invDX3 = invDX2 / mXSpacing;
  46. for (i = 0, ip1 = 1; i < quantity - 1; ++i, ++ip1)
  47. {
  48. auto& poly = this->mPoly[i];
  49. Real F0 = F[i];
  50. Real F1 = F[ip1];
  51. Real df = F1 - F0;
  52. Real FDer0 = FDer[i];
  53. Real FDer1 = FDer[ip1];
  54. poly[0] = F0;
  55. poly[1] = FDer0;
  56. poly[2] = ((Real)3 * df - mXSpacing * (FDer1 + (Real)2 * FDer0)) * invDX2;
  57. poly[3] = (mXSpacing * (FDer0 + FDer1) - (Real)2 * df) * invDX3;
  58. }
  59. }
  60. virtual ~IntpAkimaUniform1() = default;
  61. // Member access.
  62. inline virtual Real GetXMin() const override
  63. {
  64. return mXMin;
  65. }
  66. inline virtual Real GetXMax() const override
  67. {
  68. return mXMax;
  69. }
  70. inline Real GetXSpacing() const
  71. {
  72. return mXSpacing;
  73. }
  74. protected:
  75. virtual void Lookup(Real x, int& index, Real& dx) const override
  76. {
  77. // The caller has ensured that mXMin <= x <= mXMax.
  78. for (index = 0; index + 1 < this->mQuantity; ++index)
  79. {
  80. if (x < mXMin + mXSpacing * (index + 1))
  81. {
  82. dx = x - (mXMin + mXSpacing * index);
  83. return;
  84. }
  85. }
  86. --index;
  87. dx = x - (mXMin + mXSpacing * index);
  88. }
  89. Real mXMin, mXMax, mXSpacing;
  90. };
  91. }