123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- #pragma once
- #include <Mathematics/IntrSegment2Segment2.h>
- #include <set>
- #include <vector>
- namespace WwiseGTE
- {
- template <typename Real>
- class Polygon2
- {
- public:
-
-
-
-
-
-
-
- Polygon2(Vector2<Real> const* vertexPool, int numIndices,
- int const* indices, bool counterClockwise)
- :
- mVertexPool(vertexPool),
- mCounterClockwise(counterClockwise)
- {
- if (numIndices >= 3 && vertexPool && indices)
- {
- for (int i = 0; i < numIndices; ++i)
- {
- mVertices.insert(indices[i]);
- }
- if (numIndices == static_cast<int>(mVertices.size()))
- {
- mIndices.resize(numIndices);
- std::copy(indices, indices + numIndices, mIndices.begin());
- return;
- }
-
-
- mVertices.clear();
- }
-
- mVertexPool = nullptr;
- mCounterClockwise = false;
- }
-
-
-
- inline operator bool() const
- {
- return mVertexPool != nullptr;
- }
-
- inline Vector2<Real> const* GetVertexPool() const
- {
- return mVertexPool;
- }
- inline std::set<int> const& GetVertices() const
- {
- return mVertices;
- }
- inline std::vector<int> const& GetIndices() const
- {
- return mIndices;
- }
- inline bool CounterClockwise() const
- {
- return mCounterClockwise;
- }
-
- Vector2<Real> ComputeVertexAverage() const
- {
- Vector2<Real> average = Vector2<Real>::Zero();
- if (mVertexPool)
- {
- for (int index : mVertices)
- {
- average += mVertexPool[index];
- }
- average /= static_cast<Real>(mVertices.size());
- }
- return average;
- }
- Real ComputePerimeterLength() const
- {
- Real length(0);
- if (mVertexPool)
- {
- Vector2<Real> v0 = mVertexPool[mIndices.back()];
- for (int index : mIndices)
- {
- Vector2<Real> v1 = mVertexPool[index];
- length += Length(v1 - v0);
- v0 = v1;
- }
- }
- return length;
- }
- Real ComputeArea() const
- {
- Real area(0);
- if (mVertexPool)
- {
- int const numIndices = static_cast<int>(mIndices.size());
- Vector2<Real> v0 = mVertexPool[mIndices[numIndices - 2]];
- Vector2<Real> v1 = mVertexPool[mIndices[numIndices - 1]];
- for (int index : mIndices)
- {
- Vector2<Real> v2 = mVertexPool[index];
- area += v1[0] * (v2[1] - v0[1]);
- v0 = v1;
- v1 = v2;
- }
- area *= (Real)0.5;
- }
- return std::fabs(area);
- }
-
-
-
-
-
- bool IsSimple() const
- {
- if (!mVertexPool)
- {
- return false;
- }
-
-
- int const numIndices = static_cast<int>(mIndices.size());
- if (numIndices == 3)
- {
-
- return true;
- }
- return IsSimpleInternal();
- }
-
-
- bool IsConvex() const
- {
- if (!mVertexPool)
- {
- return false;
- }
-
-
- int const numIndices = static_cast<int>(mIndices.size());
- if (numIndices == 3)
- {
-
- return true;
- }
- return IsSimpleInternal() && IsConvexInternal();
- }
- private:
-
-
-
- bool IsSimpleInternal() const
- {
- Segment2<Real> seg0, seg1;
- TIQuery<Real, Segment2<Real>, Segment2<Real>> query;
- typename TIQuery<Real, Segment2<Real>, Segment2<Real>>::Result result;
- int const numIndices = static_cast<int>(mIndices.size());
- for (int i0 = 0; i0 < numIndices; ++i0)
- {
- int i0p1 = (i0 + 1) % numIndices;
- seg0.p[0] = mVertexPool[mIndices[i0]];
- seg0.p[1] = mVertexPool[mIndices[i0p1]];
- int i1min = (i0 + 2) % numIndices;
- int i1max = (i0 - 2 + numIndices) % numIndices;
- for (int i1 = i1min; i1 <= i1max; ++i1)
- {
- int i1p1 = (i1 + 1) % numIndices;
- seg1.p[0] = mVertexPool[mIndices[i1]];
- seg1.p[1] = mVertexPool[mIndices[i1p1]];
- result = query(seg0, seg1);
- if (result.intersect)
- {
- return false;
- }
- }
- }
- return true;
- }
- bool IsConvexInternal() const
- {
- Real sign = (mCounterClockwise ? (Real)1 : (Real)-1);
- int const numIndices = static_cast<int>(mIndices.size());
- for (int i = 0; i < numIndices; ++i)
- {
- int iPrev = (i + numIndices - 1) % numIndices;
- int iNext = (i + 1) % numIndices;
- Vector2<Real> vPrev = mVertexPool[mIndices[iPrev]];
- Vector2<Real> vCurr = mVertexPool[mIndices[i]];
- Vector2<Real> vNext = mVertexPool[mIndices[iNext]];
- Vector2<Real> edge0 = vCurr - vPrev;
- Vector2<Real> edge1 = vNext - vCurr;
- Real test = sign * DotPerp(edge0, edge1);
- if (test < (Real)0)
- {
- return false;
- }
- }
- return true;
- }
- Vector2<Real> const* mVertexPool;
- std::set<int> mVertices;
- std::vector<int> mIndices;
- bool mCounterClockwise;
- };
- }
|