123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #pragma once
- #include <Mathematics/Logger.h>
- #include <Mathematics/Matrix2x2.h>
- namespace WwiseGTE
- {
- template <typename Real>
- class ContEllipse2MinCR
- {
- public:
- void operator()(int numPoints, Vector2<Real> const* points,
- Vector2<Real> const& C, Matrix2x2<Real> const& R, Real D[2]) const
- {
-
-
- std::vector<Vector2<Real>> A(numPoints);
- for (int i = 0; i < numPoints; ++i)
- {
- Vector2<Real> diff = points[i] - C;
- Vector2<Real> prod = diff * R;
- A[i] = prod * prod;
- }
-
-
-
-
- std::sort(A.begin(), A.end(),
- [](Vector2<Real> const& P0, Vector2<Real> const& P1)
- {
- if (P0[0] > P1[0]) { return true; }
- if (P0[0] < P1[0]) { return false; }
- return P0[1] > P1[1];
- }
- );
- auto end = std::unique(A.begin(), A.end(),
- [](Vector2<Real> const& P0, Vector2<Real> const& P1)
- {
- return P0[0] == P1[0];
- }
- );
- A.erase(end, A.end());
-
-
-
-
- std::sort(A.begin(), A.end(),
- [](Vector2<Real> const& P0, Vector2<Real> const& P1)
- {
- if (P0[1] > P1[1])
- {
- return true;
- }
- if (P0[1] < P1[1])
- {
- return false;
- }
- return P0[0] > P1[0];
- }
- );
- end = std::unique(A.begin(), A.end(),
- [](Vector2<Real> const& P0, Vector2<Real> const& P1)
- {
- return P0[1] == P1[1];
- }
- );
- A.erase(end, A.end());
- MaxProduct(A, D);
- }
- private:
- static void MaxProduct(std::vector<Vector2<Real>>& A, Real D[2])
- {
-
-
- int numConstraints = static_cast<int>(A.size());
- std::vector<bool> used(A.size());
- std::fill(used.begin(), used.end(), false);
-
-
-
-
-
-
-
- int i, iYMin = -1;
- int iXMin = -1;
- Real axMax = (Real)0, ayMax = (Real)0;
- for (i = 0; i < numConstraints; ++i)
- {
-
-
- if (A[i][0] > axMax)
- {
- axMax = A[i][0];
- iXMin = i;
- }
-
-
- if (A[i][1] > ayMax)
- {
- ayMax = A[i][1];
- iYMin = i;
- }
- }
- LogAssert(iXMin != -1 && iYMin != -1, "Unexpected condition.");
- used[iYMin] = true;
-
-
-
-
-
- Real x0 = (Real)0, xMax = ((Real)1) / axMax;
- int j;
- for (j = 0; j < numConstraints; ++j)
- {
-
-
-
- Real x1 = xMax;
- int line = -1;
- for (i = 0; i < numConstraints; ++i)
- {
- if (!used[i])
- {
-
-
-
-
-
-
-
-
- Real det = DotPerp(A[iYMin], A[i]);
- if (det < (Real)0)
- {
-
-
-
-
-
- D[0] = (A[i][1] - A[iYMin][1]) / det;
- if (x0 < D[0] && D[0] <= x1)
- {
- line = i;
- x1 = D[0];
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- if ((Real)0.5 < A[iYMin][0] * x0)
- {
-
-
- D[0] = x0;
- D[1] = ((Real)1 - A[iYMin][0] * D[0]) / A[iYMin][1];
- break;
- }
-
- if ((Real)0.5 < A[iYMin][0] * x1)
- {
-
-
-
-
-
- D[0] = (Real)0.5 / A[iYMin][0];
- D[1] = (Real)0.5 / A[iYMin][1];
- break;
- }
-
-
- LogAssert(line != -1, "Unexpected condition.");
- x0 = x1;
- x1 = xMax;
- used[line] = true;
- iYMin = line;
- }
- LogAssert(j < numConstraints, "Unexpected condition.");
- }
- };
- }
|