123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #pragma once
- #include <Mathematics/FIQuery.h>
- #include <Mathematics/TIQuery.h>
- #include <Mathematics/Hypersphere.h>
- #include <Mathematics/Vector2.h>
- namespace WwiseGTE
- {
- template <typename Real>
- class TIQuery<Real, Circle2<Real>, Circle2<Real>>
- {
- public:
- struct Result
- {
- bool intersect;
- };
- Result operator()(Circle2<Real> const& circle0, Circle2<Real> const& circle1)
- {
- Result result;
- Vector2<Real> diff = circle0.center - circle1.center;
- result.intersect = (Length(diff) <= circle0.radius + circle1.radius);
- return result;
- }
- };
- template <typename Real>
- class FIQuery<Real, Circle2<Real>, Circle2<Real>>
- {
- public:
- struct Result
- {
- bool intersect;
-
-
-
-
-
- int numIntersections;
-
- Vector2<Real> point[2];
-
- Circle2<Real> circle;
- };
- Result operator()(Circle2<Real> const& circle0, Circle2<Real> const& circle1)
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Result result;
- Vector2<Real> U = circle1.center - circle0.center;
- Real USqrLen = Dot(U, U);
- Real R0 = circle0.radius, R1 = circle1.radius;
- Real R0mR1 = R0 - R1;
- if (USqrLen == (Real)0 && R0mR1 == (Real)0)
- {
-
- result.intersect = true;
- result.numIntersections = std::numeric_limits<int>::max();
- result.circle = circle0;
- return result;
- }
- Real R0mR1Sqr = R0mR1 * R0mR1;
- if (USqrLen < R0mR1Sqr)
- {
-
- result.intersect = false;
- result.numIntersections = 0;
- return result;
- }
- Real R0pR1 = R0 + R1;
- Real R0pR1Sqr = R0pR1 * R0pR1;
- if (USqrLen > R0pR1Sqr)
- {
-
- result.intersect = false;
- result.numIntersections = 0;
- return result;
- }
- if (USqrLen < R0pR1Sqr)
- {
- if (R0mR1Sqr < USqrLen)
- {
- Real invUSqrLen = (Real)1 / USqrLen;
- Real s = (Real)0.5 * ((R0 * R0 - R1 * R1) * invUSqrLen + (Real)1);
- Vector2<Real> tmp = circle0.center + s * U;
-
-
- Real discr = R0 * R0 * invUSqrLen - s * s;
- if (discr < (Real)0)
- {
- discr = (Real)0;
- }
- Real t = std::sqrt(discr);
- Vector2<Real> V{ U[1], -U[0] };
- result.point[0] = tmp - t * V;
- result.point[1] = tmp + t * V;
- result.numIntersections = (t > (Real)0 ? 2 : 1);
- }
- else
- {
-
- result.numIntersections = 1;
- result.point[0] = circle0.center + (R0 / R0mR1) * U;
- }
- }
- else
- {
-
- result.numIntersections = 1;
- result.point[0] = circle0.center + (R0 / R0pR1) * U;
- }
-
- result.intersect = true;
- return result;
- }
- };
- }
|