123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #pragma once
- #include <Mathematics/ContScribeCircle2.h>
- #include <vector>
- namespace WwiseGTE
- {
-
-
-
-
- template <typename Real>
- bool ApproximateEllipseByArcs(Real a, Real b, int numArcs,
- std::vector<Vector2<Real>>& points, std::vector<Vector2<Real>>& centers,
- std::vector<Real>& radii)
- {
- if (numArcs < 2 || a == b)
- {
-
-
- points.clear();
- centers.clear();
- radii.clear();
- return false;
- }
- points.resize(numArcs + 1);
- centers.resize(numArcs);
- radii.resize(numArcs);
-
- Real a2 = a * a, b2 = b * b, ab = a * b;
- Real invB2mA2 = (Real)1 / (b2 - a2);
-
-
- points[0] = { a, (Real)0 };
- points[numArcs] = { (Real)0, b };
-
-
- Real curv0 = a / b2;
- Real curv1 = b / a2;
-
- Real invNumArcs = (Real)1 / numArcs;
- for (int i = 1; i < numArcs; ++i)
- {
-
-
- Real weight1 = static_cast<Real>(i) * invNumArcs;
- Real weight0 = (Real)1 - weight1;
- Real curv = weight0 * curv0 + weight1 * curv1;
-
- Real tmp = std::pow(ab / curv, (Real)2 / (Real)3);
- points[i][0] = a * std::sqrt(std::fabs((tmp - a2) * invB2mA2));
- points[i][1] = b * std::sqrt(std::fabs((tmp - b2) * invB2mA2));
- }
-
- Circle2<Real> circle;
- Vector2<Real> const& p0 = points[0];
- Vector2<Real> const& p1 = points[1];
- if (!Circumscribe(Vector2<Real>{ p1[0], -p1[1] }, p0, p1, circle))
- {
-
- points.clear();
- centers.clear();
- radii.clear();
- return false;
- }
- centers[0] = circle.center;
- radii[0] = circle.radius;
-
- int last = numArcs - 1;
- Vector2<Real> const& pNm1 = points[last];
- Vector2<Real> const& pN = points[numArcs];
- if (!Circumscribe(Vector2<Real>{ -pNm1[0], pNm1[1] }, pN, pNm1, circle))
- {
-
- points.clear();
- centers.clear();
- radii.clear();
- return false;
- }
- centers[last] = circle.center;
- radii[last] = circle.radius;
-
- for (int iM = 0, i = 1, iP = 2; i < last; ++iM, ++i, ++iP)
- {
- Circumscribe(points[iM], points[i], points[iP], circle);
- centers[i] = circle.center;
- radii[i] = circle.radius;
- }
- return true;
- }
- }
|