123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- #pragma once
- #include <Mathematics/Matrix3x3.h>
- #include <Mathematics/SymmetricEigensolver3x3.h>
- namespace WwiseGTE
- {
-
-
-
-
-
-
- template <typename Real>
- class ApprGreatCircle3
- {
- public:
- void operator()(int numPoints, Vector3<Real> const* points, Vector3<Real>& normal) const
- {
-
- Real covar00 = (Real)0, covar01 = (Real)0, covar02 = (Real)0;
- Real covar11 = (Real)0, covar12 = (Real)0, covar22 = (Real)0;
- for (int i = 0; i < numPoints; i++)
- {
- Vector3<Real> diff = points[i];
- covar00 += diff[0] * diff[0];
- covar01 += diff[0] * diff[1];
- covar02 += diff[0] * diff[2];
- covar11 += diff[1] * diff[1];
- covar12 += diff[1] * diff[2];
- covar22 += diff[2] * diff[2];
- }
- Real invNumPoints = (Real)1 / static_cast<Real>(numPoints);
- covar00 *= invNumPoints;
- covar01 *= invNumPoints;
- covar02 *= invNumPoints;
- covar11 *= invNumPoints;
- covar12 *= invNumPoints;
- covar22 *= invNumPoints;
-
- SymmetricEigensolver3x3<Real> es;
- std::array<Real, 3> eval;
- std::array<std::array<Real, 3>, 3> evec;
- es(covar00, covar01, covar02, covar11, covar12, covar22, false, +1,
- eval, evec);
- normal = evec[0];
- }
- };
-
-
-
-
-
-
-
-
- template <typename Real>
- class ApprGreatArc3
- {
- public:
- void operator()(int numPoints, Vector3<Real> const* points,
- Vector3<Real>& normal, Vector3<Real>& arcEnd0,
- Vector3<Real>& arcEnd1) const
- {
-
-
- Vector3<Real> basis[3];
- ApprGreatCircle3<Real>()(numPoints, points, basis[0]);
- ComputeOrthogonalComplement(1, basis);
-
-
-
-
-
-
-
-
-
- std::vector<std::array<Real, 3>> items(numPoints);
- for (int i = 0; i < numPoints; ++i)
- {
- items[i][0] = Dot(basis[1], points[i]);
- items[i][1] = Dot(basis[2], points[i]);
- items[i][2] = std::atan2(items[i][1], items[i][0]);
- }
- std::sort(items.begin(), items.end(),
- [](std::array<Real, 3> const& item0, std::array<Real, 3> const& item1)
- {
- return item0[2] < item1[2];
- }
- );
-
-
-
- int numPointsM1 = numPoints - 1;
- Real maxDiff = (Real)GTE_C_TWO_PI + items[0][2] - items[numPointsM1][2];
- int end0 = 0, end1 = numPointsM1;
- for (int i0 = 0, i1 = 1; i0 < numPointsM1; i0 = i1++)
- {
- Real diff = items[i1][2] - items[i0][2];
- if (diff > maxDiff)
- {
- maxDiff = diff;
- end0 = i1;
- end1 = i0;
- }
- }
- normal = basis[0];
- arcEnd0 = items[end0][0] * basis[1] + items[end0][1] * basis[2];
- arcEnd1 = items[end1][0] * basis[1] + items[end1][1] * basis[2];
- Normalize(arcEnd0);
- Normalize(arcEnd1);
- }
- };
- }
|