ApprHeightLine2.h 3.8 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/ApprQuery.h>
  9. #include <Mathematics/Matrix2x2.h>
  10. // Least-squares fit of a line to height data (x,f(x)). The line is of the
  11. // form: (y - yAvr) = a*(x - xAvr), where (xAvr,yAvr) is the average of the
  12. // sample points. The return value of Fit is 'true' if and only if the fit is
  13. // successful (the input points are not degenerate to a single point). The
  14. // mParameters values are ((xAvr,yAvr),(a,-1)) on success and ((0,0),(0,0)) on
  15. // failure. The error for (x0,y0) is [a*(x0-xAvr)-(y0-yAvr)]^2.
  16. namespace WwiseGTE
  17. {
  18. template <typename Real>
  19. class ApprHeightLine2 : public ApprQuery<Real, Vector2<Real>>
  20. {
  21. public:
  22. // Initialize the model parameters to zero.
  23. ApprHeightLine2()
  24. {
  25. mParameters.first = Vector2<Real>::Zero();
  26. mParameters.second = Vector2<Real>::Zero();
  27. }
  28. // Basic fitting algorithm. See ApprQuery.h for the various Fit(...)
  29. // functions that you can call.
  30. virtual bool FitIndexed(
  31. size_t numPoints, Vector2<Real> const* points,
  32. size_t numIndices, int const* indices) override
  33. {
  34. if (this->ValidIndices(numPoints, points, numIndices, indices))
  35. {
  36. // Compute the mean of the points.
  37. Vector2<Real> mean = Vector2<Real>::Zero();
  38. int const* currentIndex = indices;
  39. for (size_t i = 0; i < numIndices; ++i)
  40. {
  41. mean += points[*currentIndex++];
  42. }
  43. mean /= (Real)numIndices;
  44. if (std::isfinite(mean[0]) && std::isfinite(mean[1]))
  45. {
  46. // Compute the covariance matrix of the points.
  47. Real covar00 = (Real)0, covar01 = (Real)0;
  48. currentIndex = indices;
  49. for (size_t i = 0; i < numIndices; ++i)
  50. {
  51. Vector2<Real> diff = points[*currentIndex++] - mean;
  52. covar00 += diff[0] * diff[0];
  53. covar01 += diff[0] * diff[1];
  54. }
  55. // Decompose the covariance matrix.
  56. if (covar00 > (Real)0)
  57. {
  58. mParameters.first = mean;
  59. mParameters.second[0] = covar01 / covar00;
  60. mParameters.second[1] = (Real)-1;
  61. return true;
  62. }
  63. }
  64. }
  65. mParameters.first = Vector2<Real>::Zero();
  66. mParameters.second = Vector2<Real>::Zero();
  67. return false;
  68. }
  69. // Get the parameters for the best fit.
  70. std::pair<Vector2<Real>, Vector2<Real>> const& GetParameters() const
  71. {
  72. return mParameters;
  73. }
  74. virtual size_t GetMinimumRequired() const override
  75. {
  76. return 2;
  77. }
  78. virtual Real Error(Vector2<Real> const& point) const override
  79. {
  80. Real d = Dot(point - mParameters.first, mParameters.second);
  81. Real error = d * d;
  82. return error;
  83. }
  84. virtual void CopyParameters(ApprQuery<Real, Vector2<Real>> const* input) override
  85. {
  86. auto source = dynamic_cast<ApprHeightLine2<Real> const*>(input);
  87. if (source)
  88. {
  89. *this = *source;
  90. }
  91. }
  92. private:
  93. std::pair<Vector2<Real>, Vector2<Real>> mParameters;
  94. };
  95. }