ApprHeightPlane3.h 4.4 KB

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