UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Polygon2.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// port of geometry3Sharp Polygon
4
5#pragma once
6
8#include "Math/UnrealMath.h"
9#include "VectorTypes.h"
10#include "BoxTypes.h"
11#include "SegmentTypes.h"
12#include "LineTypes.h"
13#include "MathUtil.h"
15#include "Curve/CurveUtil.h"
16#include "Algo/Reverse.h"
17
18namespace UE
19{
20namespace Geometry
21{
22
23using namespace UE::Math;
24
28template<typename T>
30{
31
32protected:
35
36public:
37
39 {
40 }
41
48
49 template<typename OtherVertexType>
51 {
52 Vertices.Reserve(VertexList.Num());
54 {
56 }
57 }
58
59
64 {
65 Vertices.SetNum(VertexIndices.Num());
66 for (int32 Idx = 0; Idx < VertexIndices.Num(); Idx++)
67 {
68 Vertices[Idx] = VertexArray[VertexIndices[Idx]];
69 }
70 }
71
75 const TVector2<T>& operator[](int Index) const
76 {
77 return Vertices[Index];
78 }
79
84 {
85 return Vertices[Index];
86 }
87
88
92 const TVector2<T>& Start() const
93 {
94 return Vertices[0];
95 }
96
101 {
102 return Vertices;
103 }
104
108 int VertexCount() const
109 {
110 return Vertices.Num();
111 }
112
117 {
118 Vertices.Add(Position);
119 }
120
124 void AppendVertices(const TArray<TVector2<T>>& NewVertices)
125 {
126 Vertices.Append(NewVertices);
127 }
128
132 void Set(int VertexIndex, const TVector2<T>& Position)
133 {
134 Vertices[VertexIndex] = Position;
135 }
136
140 void RemoveVertex(int VertexIndex)
141 {
142 Vertices.RemoveAt(VertexIndex);
143 }
144
148 void SetVertices(const TArray<TVector2<T>>& NewVertices)
149 {
150 Vertices = NewVertices;
151 }
152
153
157 void Reverse()
158 {
160 }
161
162
167 TVector2<T> GetTangent(int VertexIndex) const
168 {
169 return CurveUtil::Tangent<T, TVector2<T>, true>(Vertices, VertexIndex);
170 }
171
172
177 TVector2<T> GetNormal(int VertexIndex) const
178 {
179 return PerpCW(GetTangent(VertexIndex));
180 }
181
182
188 TVector2<T> GetNormal_FaceAvg(int VertexIndex) const
189 {
190 return CurveUtil::GetNormal_FaceAvg2<T, TVector2<T>, true>(Vertices, VertexIndex);
191 }
192
193
198 {
200 }
201
202
207 {
208 public:
209 inline bool operator!()
210 {
211 return i < polygon->VertexCount();
212 }
213 inline TSegment2<T> operator*() const
214 {
215 check(polygon != nullptr && i < polygon->VertexCount());
217 }
218 //inline TSegment2<T> & operator*();
219 inline SegmentIterator & operator++() // prefix
220 {
221 i++;
222 return *this;
223 }
224 inline SegmentIterator operator++(int) // postfix
225 {
226 SegmentIterator copy(*this);
227 i++;
228 return copy;
229 }
230 inline bool operator==(const SegmentIterator & i2) const { return i2.polygon == polygon && i2.i == i; }
231 inline bool operator!=(const SegmentIterator & i2) const { return i2.polygon != polygon || i2.i != i; }
232 protected:
234 int i;
235 inline SegmentIterator(const TPolygon2 * p, int iCur) : polygon(p), i(iCur) {}
236 friend class TPolygon2;
237 };
238 friend class SegmentIterator;
239
241 {
242 return SegmentIterator(this, 0);
243 }
244
249 {
250 public:
254 SegmentIterator begin() { return polygon->SegmentItr(); }
255 SegmentIterator end() { return SegmentIterator(polygon, polygon->VertexCount()); }
256 };
257
262 {
263 return SegmentEnumerable(this);
264 }
265
266
270 bool IsClockwise() const
271 {
272 return SignedArea() < 0;
273 }
274
278 T SignedArea() const
279 {
280 return CurveUtil::SignedArea2<T, TVector2<T>>(Vertices);
281 }
282
286 T Area() const
287 {
289 }
290
294 T Perimeter() const
295 {
296 return CurveUtil::ArcLength<T, TVector2<T>>(Vertices, true);
297 }
298
299
304 {
305 CurveUtil::GetPrevNext<T, TVector2<T>, true>(Vertices, VertexIdx, OutPrevNbr, OutNextNbr);
306 }
307
308
313 {
314 CurveUtil::GetVectorsToPrevNext<T, TVector2<T>, true>(Vertices, VertexIdx, OutToPrev, OutToNext, bNormalize);
315 }
316
317
322 {
324 NeighbourVectors(iVertex, e0, e1, true);
325 return AngleD(e0, e1);
326 }
327
328
333 {
334 return CurveUtil::WindingIntegral2<T, TVector2<T>>(Vertices, QueryPoint);
335 }
336
343 {
344 return CurveUtil::IsConvex2<T, TVector2<T>>(Vertices, RadiansTolerance, bDegenerateIsConvex);
345 }
346
347
351 bool Contains(const TVector2<T>& QueryPoint) const
352 {
353 return CurveUtil::Contains2<T, TVector2<T>>(Vertices, QueryPoint);
354 }
355
361 bool Overlaps(const TPolygon2<T>& OtherPoly) const
362 {
363 if (!Bounds().Intersects(OtherPoly.Bounds()))
364 {
365 return false;
366 }
367
368 for (int i = 0, N = OtherPoly.VertexCount(); i < N; ++i)
369 {
370 if (Contains(OtherPoly[i]))
371 {
372 return true;
373 }
374 }
375
376 for (int i = 0, N = VertexCount(); i < N; ++i)
377 {
378 if (OtherPoly.Contains(Vertices[i]))
379 {
380 return true;
381 }
382 }
383
384 for (TSegment2<T> seg : Segments())
385 {
386 for (TSegment2<T> oseg : OtherPoly.Segments())
387 {
388 if (seg.Intersects(oseg))
389 {
390 return true;
391 }
392 }
393 }
394 return false;
395 }
396
400 bool Contains(const TPolygon2<T>& OtherPoly) const
401 {
402 // @todo fast bbox check?
403
404 int N = OtherPoly.VertexCount();
405 for (int i = 0; i < N; ++i)
406 {
407 if (Contains(OtherPoly[i]) == false)
408 {
409 return false;
410 }
411 }
412
414 {
415 return false;
416 }
417
418 return true;
419 }
420
421
425 bool Contains(const TSegment2<T>& Segment) const
426 {
427 // [TODO] Add bbox check
428 if (Contains(Segment.StartPoint()) == false || Contains(Segment.EndPoint()) == false)
429 {
430 return false;
431 }
432
433 for (TSegment2<T> seg : Segments())
434 {
435 if (seg.Intersects(Segment))
436 {
437 return false;
438 }
439 }
440 return true;
441 }
442
447 {
448 CurveUtil::ClipConvexToBounds<T, TVector2<T>, true, 2>(Vertices, Bounds.Min, Bounds.Max);
449 }
450
451
456 {
457 if (!Bounds().Intersects(OtherPoly.Bounds()))
458 {
459 return false;
460 }
461
462 for (TSegment2<T> seg : Segments())
463 {
464 for (TSegment2<T> oseg : OtherPoly.Segments())
465 {
466 if (seg.Intersects(oseg))
467 {
468 return true;
469 }
470 }
471 }
472 return false;
473 }
474
475
479 bool Intersects(const TSegment2<T>& Segment) const
480 {
481 // [TODO] Add bbox check
482 if (Contains(Segment.StartPoint()) == true || Contains(Segment.EndPoint()) == true)
483 {
484 return true;
485 }
486
487 // [TODO] Add bbox check
488 for (TSegment2<T> seg : Segments())
489 {
490 if (seg.Intersects(Segment))
491 {
492 return true;
493 }
494 }
495 return false;
496 }
497
498
506 {
507 if (!Bounds().Intersects(OtherPoly.Bounds()))
508 {
509 return false;
510 }
511
512 bool bFoundIntersections = false;
513 for (TSegment2<T> seg : Segments())
514 {
515 for (TSegment2<T> oseg : OtherPoly.Segments())
516 {
517 // this computes test twice for intersections, but seg.intersects doesn't
518 // create any new objects so it should be much faster for majority of segments (should profile!)
519 if (seg.Intersects(oseg))
520 {
521 //@todo can we replace with something like seg.intersects?
523 if (intr.Find())
524 {
525 bFoundIntersections = true;
526 OutArray.Add(intr.Point0);
527 if (intr.Quantity == 2)
528 {
529 OutArray.Add(intr.Point1);
530 }
531 }
532 }
533 }
534 }
535
536 return bFoundIntersections;
537 }
538
539
543 TSegment2<T> Segment(int SegmentIndex) const
544 {
545 return TSegment2<T>(Vertices[SegmentIndex], Vertices[(SegmentIndex + 1) % Vertices.Num()]);
546 }
547
553 TVector2<T> GetSegmentPoint(int SegmentIndex, T SegmentParam) const
554 {
555 TSegment2<T> seg(Vertices[SegmentIndex], Vertices[(SegmentIndex + 1) % Vertices.Num()]);
556 return seg.PointAt(SegmentParam);
557 }
558
564 TVector2<T> GetSegmentPointUnitParam(int SegmentIndex, T SegmentParam) const
565 {
566 TSegment2<T> seg(Vertices[SegmentIndex], Vertices[(SegmentIndex + 1) % Vertices.Num()]);
567 return seg.PointBetween(SegmentParam);
568 }
569
570
576 TVector2<T> GetNormal(int iSeg, T SegmentParam) const
577 {
578 TSegment2<T> seg(Vertices[iSeg], Vertices[(iSeg + 1) % Vertices.Num()]);
579 T t = ((SegmentParam / seg.Extent) + 1.0) / 2.0;
580
582 TVector2<T> n1 = GetNormal((iSeg + 1) % Vertices.Num());
583 return Normalized((T(1) - t) * n0 + t * n1);
584 }
585
586
587
596 {
599 T dist = TNumericLimits<T>::Max();
600 int N = Vertices.Num();
601 for (int vi = 0; vi < N; ++vi)
602 {
603 // @todo can't we just use segment function here now?
604 TSegment2<T> seg = TSegment2<T>(Vertices[vi], Vertices[(vi + 1) % N]);
605 T t = (QueryPoint - seg.Center).Dot(seg.Direction);
607 if (t >= seg.Extent)
608 {
610 }
611 else if (t <= -seg.Extent)
612 {
614 }
615 else
616 {
617 d = (seg.PointAt(t) - QueryPoint).SquaredLength();
618 }
619 if (d < dist)
620 {
621 dist = d;
624 }
625 }
626 return dist;
627 }
628
629
636 {
637 int seg; T segt;
638 return DistanceSquared(QueryPoint, seg, segt);
639 }
640
641
646 {
647 T avg = 0; int N = Vertices.Num();
648 for (int i = 1; i < N; ++i) {
649 avg += Distance(Vertices[i], Vertices[i - 1]);
650 }
651 avg += Distance(Vertices[N - 1], Vertices[0]);
652 return avg / N;
653 }
654
655
661 {
662 int N = Vertices.Num();
663 for (int i = 0; i < N; ++i)
664 {
665 Vertices[i] += Translate;
666 }
667 return *this;
668 }
669
675 {
676 int N = Vertices.Num();
677 for (int i = 0; i < N; ++i)
678 {
679 Vertices[i] = Scale * (Vertices[i] - Origin) + Origin;
680 }
681 return *this;
682 }
683
684
690 {
691 int N = Vertices.Num();
692 for (int i = 0; i < N; ++i)
693 {
695 }
696 return *this;
697 }
698
699
700
701
708 {
709 TArray<TVector2<T>> NewVertices;
710 NewVertices.SetNumUninitialized(Vertices.Num());
711 if (bUseFaceAvg)
712 {
713 for (int k = 0; k < Vertices.Num(); ++k)
714 {
715 NewVertices[k] = Vertices[k] + OffsetDistance * GetNormal_FaceAvg(k);
716 }
717 }
718 else
719 {
720 for (int k = 0; k < Vertices.Num(); ++k)
721 {
722 NewVertices[k] = Vertices[k] + OffsetDistance * GetNormal(k);
723 }
724 }
725 for (int k = 0; k < Vertices.Num(); ++k)
726 {
727 Vertices[k] = NewVertices[k];
728 }
729 }
730
731
737 {
738 // [TODO] possibly can do with half as many normalizes if we do w/ sequential edges,
739 // rather than centering on each v?
740 TArray<TVector2<T>> NewVertices;
741 NewVertices.SetNumUninitialized(Vertices.Num());
742 for (int k = 0; k < Vertices.Num(); ++k)
743 {
745 TVector2<T> next = Vertices[(k + 1) % Vertices.Num()];
746 TVector2<T> prev = Vertices[k == 0 ? Vertices.Num() - 1 : k - 1];
750 TLine2<T> lp(v - OffsetDistance * PerpCW(dp), dp);
751
752 bool bIntersectsAtPoint = ln.IntersectionPoint(lp, NewVertices[k]);
753 if (!bIntersectsAtPoint) // lines were parallel
754 {
755 NewVertices[k] = Vertices[k] + OffsetDistance * GetNormal_FaceAvg(k);
756 }
757 }
758 for (int k = 0; k < Vertices.Num(); ++k)
759 {
760 Vertices[k] = NewVertices[k];
761 }
762 }
763
764
765private:
766 // Polygon simplification
767 // code adapted from: http://softsurfer.com/Archive/algorithm_0205/algorithm_0205.htm
768 // simplifyDP():
769 // This is the Douglas-Peucker recursive simplification routine
770 // It just marks Vertices that are part of the simplified polyline
771 // for approximating the polyline subchain v[j] to v[k].
772 // Input: tol = approximation tolerance
773 // v[] = polyline array of vertex points
774 // j,k = indices for the subchain v[j] to v[k]
775 // Output: mk[] = array of markers matching vertex array v[]
776 static void SimplifyDouglasPeucker(T Tolerance, const TArray<TVector2<T>>& Vertices, int j, int k, TArray<bool>& Marked)
777 {
778 Marked.SetNum(Vertices.Num());
779 if (k <= j + 1) // there is nothing to simplify
780 return;
781
782 // check for adequate approximation by segment S from v[j] to v[k]
783 int maxi = j; // index of vertex farthest from S
784 T maxd2 = 0; // distance squared of farthest vertex
785 T tol2 = Tolerance * Tolerance; // tolerance squared
786 TSegment2<T> S = TSegment2<T>(Vertices[j], Vertices[k]); // segment from v[j] to v[k]
787
788 // test each vertex v[i] for max distance from S
789 // Note: this works in any dimension (2D, 3D, ...)
790 for (int i = j + 1; i < k; i++)
791 {
792 T dv2 = S.DistanceSquared(Vertices[i]);
793 if (dv2 <= maxd2)
794 continue;
795 // v[i] is a max vertex
796 maxi = i;
797 maxd2 = dv2;
798 }
799 if (maxd2 > tol2) // error is worse than the tolerance
800 {
801 // split the polyline at the farthest vertex from S
802 Marked[maxi] = true; // mark v[maxi] for the simplified polyline
803 // recursively simplify the two subpolylines at v[maxi]
804 SimplifyDouglasPeucker(Tolerance, Vertices, j, maxi, Marked); // polyline v[j] to v[maxi]
805 SimplifyDouglasPeucker(Tolerance, Vertices, maxi, k, Marked); // polyline v[maxi] to v[k]
806 }
807 // else the approximation is OK, so ignore intermediate Vertices
808 return;
809 }
810
811
812public:
813
820 {
821 int n = Vertices.Num();
822 if (n < 3)
823 {
824 return;
825 }
826
827 int i, k, pv; // misc counters
828 TArray<TVector2<T>> NewVertices;
829 NewVertices.SetNumUninitialized(n + 1); // vertex buffer
830 TArray<bool> Marked;
831 Marked.SetNumUninitialized(n + 1);
832 for (i = 0; i < n + 1; ++i) // marker buffer
833 {
834 Marked[i] = false;
835 }
836
837 // STAGE 1. Vertex Reduction within tolerance of prior vertex cluster
839 NewVertices[0] = Vertices[0]; // start at the beginning
840 for (i = 1, k = 1, pv = 0; i < n; i++)
841 {
843 {
844 continue;
845 }
846 NewVertices[k++] = Vertices[i];
847 pv = i;
848 }
849 bool skip_dp = false;
850 if (k == 1)
851 {
852 NewVertices[k++] = Vertices[1];
853 NewVertices[k++] = Vertices[2];
854 skip_dp = true;
855 }
856 else if (k == 2)
857 {
858 if (pv + 1 < n) // pv < n-1 case; use vertex pv+1
859 {
860 NewVertices[2] = Vertices[pv + 1];
861 }
862 else // pv == n-1 case; use vertices n-2 and n-1
863 {
864 NewVertices[1] = Vertices[pv - 1];
865 NewVertices[2] = Vertices[pv];
866 }
867 k = 3;
868 skip_dp = true;
869 }
870
871 // push on start vertex again, because simplifyDP is for polylines, not polygons
872 NewVertices[k++] = Vertices[0];
873
874 // STAGE 2. Douglas-Peucker polyline simplification
875 int nv = 0;
876 if (skip_dp == false && LineDeviationTolerance > 0)
877 {
878 Marked[0] = Marked[k - 1] = true; // mark the first and last Vertices
879 SimplifyDouglasPeucker(LineDeviationTolerance, NewVertices, 0, k - 1, Marked);
880 for (i = 0; i < k - 1; ++i)
881 {
882 if (Marked[i])
883 {
884 nv++;
885 }
886 }
887 }
888 else
889 {
890 for (i = 0; i < k; ++i)
891 {
892 Marked[i] = true;
893 }
894 nv = k - 1;
895 }
896
897 // polygon requires at least 3 Vertices
898 if (nv == 2)
899 {
900 for (i = 1; i < k - 1; ++i)
901 {
902 if (Marked[1] == false)
903 {
904 Marked[1] = true;
905 }
906 else if (Marked[k - 2] == false)
907 {
908 Marked[k - 2] = true;
909 }
910 }
911 nv++;
912 }
913 else if (nv == 1)
914 {
915 Marked[1] = true;
916 Marked[2] = true;
917 nv += 2;
918 }
919
920 // copy marked Vertices back to this polygon
921 Vertices.Reset();
922 for (i = 0; i < k - 1; ++i) // last vtx is copy of first, and definitely marked
923 {
924 if (Marked[i])
925 {
926 Vertices.Add(NewVertices[i]);
927 }
928 }
929
930 return;
931 }
932
933
934
940 {
942
944 int N = OldV.Num();
945 Vertices.Reset();
946
947 int iCur = 0;
948 do {
949 TVector2<T> center = OldV[iCur];
950
951 int iPrev = (iCur == 0) ? N - 1 : iCur - 1;
953 int iNext = (iCur + 1) % N;
955
956 TVector2<T> cp = prev - center;
957 T cpdist = Normalize(cp);
959 T cndist = Normalize(cn);
960
961 // if degenerate, skip this vert
963 {
964 iCur = iNext;
965 continue;
966 }
967
968 T angle = AngleD(cp, cn);
969 // TODO document what this means sign-wise
970 // TODO re-test post Unreal port that this DotPerp is doing the right thing
971 T sign = DotPerp(cn, cp);
972 bool bConcave = (sign > 0);
973
975
976 // ok not too sharp
977 if (angle > thresh)
978 {
979 Vertices.Add(center);
980 iCur = iNext;
981 continue;
982 }
983
984
989
990 Vertices.Add(prev_cut);
991 Vertices.Add(next_cut);
992 iCur = iNext;
993 } while (iCur != 0);
994 }
995
996
997
998
1002 static TPolygon2<T> MakeRectangle(const TVector2<T>& Center, T Width, T Height)
1003 {
1005 Rectangle.Vertices.SetNumUninitialized(4);
1006 Rectangle.Set(0, TVector2<T>(Center.X - Width / 2, Center.Y - Height / 2));
1007 Rectangle.Set(1, TVector2<T>(Center.X + Width / 2, Center.Y - Height / 2));
1008 Rectangle.Set(2, TVector2<T>(Center.X + Width / 2, Center.Y + Height / 2));
1009 Rectangle.Set(3, TVector2<T>(Center.X - Width / 2, Center.Y + Height / 2));
1010 return Rectangle;
1011 }
1012
1016 static TPolygon2<T> MakeRoundedRectangle(const TVector2<T>& Center, T Width, T Height, T Corner, int CornerSteps)
1017 {
1019 CornerSteps = FMath::Max(2, CornerSteps);
1020 RRectangle.Vertices.SetNumUninitialized(CornerSteps * 4);
1021
1022 TVector2<T> InnerExtents(Width*.5 - Corner, Height*.5 - Corner);
1024 {
1029 };
1030
1032 for (int StepIdx = 0; StepIdx < CornerSteps; StepIdx++)
1033 {
1034 T Angle = StepIdx * IdxToAng;
1035 T OffC = TMathUtil<T>::Cos(Angle) * Corner;
1036 T OffS = TMathUtil<T>::Sin(Angle) * Corner;
1041 }
1042 return RRectangle;
1043 }
1044
1045
1049 static TPolygon2<T> MakeCircle(T Radius, int Steps, T AngleShiftRadians = 0)
1050 {
1052 Circle.Vertices.SetNumUninitialized(Steps);
1053
1054 for (int i = 0; i < Steps; ++i)
1055 {
1056 T t = (T)i / (T)Steps;
1058 Circle.Set(i, TVector2<T>(Radius * TMathUtil<T>::Cos(a), Radius * TMathUtil<T>::Sin(a)));
1059 }
1060
1061 return Circle;
1062 }
1063
1064};
1065
1068
1069} // end namespace UE::Geometry
1070} // end namespace UE
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
int prev(int i, int n)
Definition RecastMesh.cpp:163
int next(int i, int n)
Definition RecastMesh.cpp:164
Definition ArrayView.h:139
UE_FORCEINLINE_HINT constexpr SizeType Num() const
Definition ArrayView.h:380
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
Definition AndroidPlatformMisc.h:14
Definition MathUtil.h:150
static RealType Cos(const RealType Value)
Definition MathUtil.h:372
static RealType Sin(const RealType Value)
Definition MathUtil.h:366
static RealType Clamp(const RealType Value, const RealType ClampMin, const RealType ClampMax)
Definition MathUtil.h:222
static RealType Abs(const RealType Value)
Definition MathUtil.h:215
static RealType Min(const RealType A, const RealType B)
Definition MathUtil.h:271
Definition IntrSegment2Segment2.h:57
SegmentEnumerable(const TPolygon2< T > *p)
Definition Polygon2.h:253
SegmentIterator end()
Definition Polygon2.h:255
SegmentIterator begin()
Definition Polygon2.h:254
const TPolygon2< T > * polygon
Definition Polygon2.h:251
SegmentEnumerable()
Definition Polygon2.h:252
SegmentIterator(const TPolygon2 *p, int iCur)
Definition Polygon2.h:235
SegmentIterator operator++(int)
Definition Polygon2.h:224
SegmentIterator & operator++()
Definition Polygon2.h:219
bool operator!=(const SegmentIterator &i2) const
Definition Polygon2.h:231
TSegment2< T > operator*() const
Definition Polygon2.h:213
bool operator!()
Definition Polygon2.h:209
int i
Definition Polygon2.h:234
const TPolygon2 * polygon
Definition Polygon2.h:233
bool operator==(const SegmentIterator &i2) const
Definition Polygon2.h:230
Definition Polygon2.h:30
SegmentIterator SegmentItr() const
Definition Polygon2.h:240
void RemoveVertex(int VertexIndex)
Definition Polygon2.h:140
bool IsConvex(T RadiansTolerance=TMathUtil< T >::ZeroTolerance, bool bDegenerateIsConvex=true) const
Definition Polygon2.h:342
static TPolygon2< T > MakeRectangle(const TVector2< T > &Center, T Width, T Height)
Definition Polygon2.h:1002
T AverageEdgeLength() const
Definition Polygon2.h:645
TVector2< T > GetSegmentPointUnitParam(int SegmentIndex, T SegmentParam) const
Definition Polygon2.h:564
bool Intersects(const TPolygon2< T > &OtherPoly) const
Definition Polygon2.h:455
TVector2< T > & operator[](int Index)
Definition Polygon2.h:83
int VertexCount() const
Definition Polygon2.h:108
TPolygon2(const TArray< TVector2< T > > &VertexList)
Definition Polygon2.h:45
TVector2< T > GetNormal(int VertexIndex) const
Definition Polygon2.h:177
T DistanceSquared(const TVector2< T > &QueryPoint) const
Definition Polygon2.h:635
SegmentEnumerable Segments() const
Definition Polygon2.h:261
void VtxNormalOffset(T OffsetDistance, bool bUseFaceAvg=false)
Definition Polygon2.h:707
TPolygon2< T > & Transform(const TFunction< TVector2< T >(const TVector2< T > &)> &TransformFunc)
Definition Polygon2.h:689
TVector2< T > GetSegmentPoint(int SegmentIndex, T SegmentParam) const
Definition Polygon2.h:553
TPolygon2< T > & Scale(const TVector2< T > &Scale, const TVector2< T > &Origin)
Definition Polygon2.h:674
bool IsClockwise() const
Definition Polygon2.h:270
void Simplify(T ClusterTolerance=0.0001, T LineDeviationTolerance=0.01)
Definition Polygon2.h:819
bool Contains(const TSegment2< T > &Segment) const
Definition Polygon2.h:425
TPolygon2< T > & Translate(const TVector2< T > &Translate)
Definition Polygon2.h:660
T Area() const
Definition Polygon2.h:286
bool Overlaps(const TPolygon2< T > &OtherPoly) const
Definition Polygon2.h:361
const TVector2< T > & operator[](int Index) const
Definition Polygon2.h:75
void SetVertices(const TArray< TVector2< T > > &NewVertices)
Definition Polygon2.h:148
T Perimeter() const
Definition Polygon2.h:294
bool Contains(const TVector2< T > &QueryPoint) const
Definition Polygon2.h:351
void Reverse()
Definition Polygon2.h:157
void NeighbourVectors(int VertexIdx, TVector2< T > &OutToPrev, TVector2< T > &OutToNext, bool bNormalize=false) const
Definition Polygon2.h:312
const TArray< TVector2< T > > & GetVertices() const
Definition Polygon2.h:100
void ClipConvex(const TAxisAlignedBox2< T > &Bounds)
Definition Polygon2.h:446
static TPolygon2< T > MakeCircle(T Radius, int Steps, T AngleShiftRadians=0)
Definition Polygon2.h:1049
bool FindIntersections(const TPolygon2< T > &OtherPoly, TArray< TVector2< T > > &OutArray) const
Definition Polygon2.h:505
bool Intersects(const TSegment2< T > &Segment) const
Definition Polygon2.h:479
TVector2< T > GetTangent(int VertexIndex) const
Definition Polygon2.h:167
void AppendVertices(const TArray< TVector2< T > > &NewVertices)
Definition Polygon2.h:124
TArray< TVector2< T > > Vertices
Definition Polygon2.h:34
TAxisAlignedBox2< T > Bounds() const
Definition Polygon2.h:197
void Set(int VertexIndex, const TVector2< T > &Position)
Definition Polygon2.h:132
static TPolygon2< T > MakeRoundedRectangle(const TVector2< T > &Center, T Width, T Height, T Corner, int CornerSteps)
Definition Polygon2.h:1016
TPolygon2()
Definition Polygon2.h:38
void Chamfer(T ChamferDist, T MinConvexAngleDeg=30, T MinConcaveAngleDeg=30)
Definition Polygon2.h:939
void NeighbourPoints(int VertexIdx, TVector2< T > &OutPrevNbr, TVector2< T > &OutNextNbr) const
Definition Polygon2.h:303
T DistanceSquared(const TVector2< T > &QueryPoint, int &NearestSegIndexOut, T &NearestSegParamOut) const
Definition Polygon2.h:595
TPolygon2(const TArray< OtherVertexType > &VertexList)
Definition Polygon2.h:50
TSegment2< T > Segment(int SegmentIndex) const
Definition Polygon2.h:543
TVector2< T > GetNormal_FaceAvg(int VertexIndex) const
Definition Polygon2.h:188
T SignedArea() const
Definition Polygon2.h:278
bool Contains(const TPolygon2< T > &OtherPoly) const
Definition Polygon2.h:400
TPolygon2(TArrayView< const TVector2< T > > VertexArray, TArrayView< const int32 > VertexIndices)
Definition Polygon2.h:63
TVector2< T > GetNormal(int iSeg, T SegmentParam) const
Definition Polygon2.h:576
T OpeningAngleDeg(int iVertex) const
Definition Polygon2.h:321
T WindingIntegral(const TVector2< T > &QueryPoint) const
Definition Polygon2.h:332
void AppendVertex(const TVector2< T > &Position)
Definition Polygon2.h:116
void PolyOffset(T OffsetDistance)
Definition Polygon2.h:736
const TVector2< T > & Start() const
Definition Polygon2.h:92
UE_REWRITE void Reverse(T(&Array)[ArraySize])
Definition Reverse.h:28
TPolygon2< float > FPolygon2f
Definition Polygon2.h:1067
constexpr UE::Math::TVector2< T > PerpCW(const UE::Math::TVector2< T > &V)
Definition VectorTypes.h:26
T AngleD(const UE::Math::TVector2< T > &V1, const UE::Math::TVector2< T > &V2)
Definition VectorTypes.h:92
constexpr T DotPerp(const UE::Math::TVector2< T > &V1, const UE::Math::TVector2< T > &V2)
Definition VectorTypes.h:19
T DistanceSquared(const UE::Math::TVector2< T > &V1, const UE::Math::TVector2< T > &V2)
Definition VectorTypes.h:82
T SquaredLength(const UE::Math::TVector< T > &V)
Definition VectorTypes.h:154
TPolygon2< double > FPolygon2d
Definition Polygon2.h:1066
T Normalize(UE::Math::TVector2< T > &Vector, const T Epsilon=0)
Definition VectorTypes.h:46
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
Definition ClothingSystemRuntimeModuleNv.h:10
float v
Definition radaudio_mdct.cpp:62
U16 Index
Definition radfft.cpp:71
Definition NumericLimits.h:41
Definition BoxTypes.h:637
TVector2< RealType > Max
Definition BoxTypes.h:639
TVector2< RealType > Min
Definition BoxTypes.h:638
Definition LineTypes.h:23
bool IntersectionPoint(const TLine2< T > &OtherLine, TVector2< T > &IntersectionPointOut, T ParallelDotTolerance=TMathUtil< T >::ZeroTolerance) const
Definition LineTypes.h:115
Definition SegmentTypes.h:23
TVector2< T > EndPoint() const
Definition SegmentTypes.h:85
TVector2< T > PointBetween(T UnitParameter) const
Definition SegmentTypes.h:115
T Extent
Definition SegmentTypes.h:30
TVector2< T > StartPoint() const
Definition SegmentTypes.h:79
TVector2< T > Direction
Definition SegmentTypes.h:28
TVector2< T > Center
Definition SegmentTypes.h:26
TVector2< T > PointAt(T DistanceParameter) const
Definition SegmentTypes.h:106
Definition Vector2D.h:38