2 using System.Collections.Generic;
4 using Microsoft.Xna.Framework;
8 readonly record
struct Quad2D(Vector2 A, Vector2 B, Vector2 C, Vector2 D)
10 public Vector2 Centroid => (A + B + C + D) / 4;
12 public static Quad2D FromRectangle(RectangleF rectangle)
15 A: (rectangle.Left, rectangle.Top),
16 B: (rectangle.Right, rectangle.Top),
17 C: (rectangle.Right, rectangle.Bottom),
18 D: (rectangle.Left, rectangle.Bottom));
21 public static Quad2D FromSubmarineRectangle(RectangleF rectangle)
24 A: (rectangle.X, rectangle.Y),
25 B: (rectangle.X + rectangle.Width, rectangle.Y),
26 C: (rectangle.X + rectangle.Width, rectangle.Y - rectangle.Height),
27 D: (rectangle.X, rectangle.Y - rectangle.Height));
30 public Quad2D Rotated(
float radians)
33 A: MathUtils.RotatePointAroundTarget(point: A, target: Centroid, radians: radians),
34 B: MathUtils.RotatePointAroundTarget(point: B, target: Centroid, radians: radians),
35 C: MathUtils.RotatePointAroundTarget(point: C, target: Centroid, radians: radians),
36 D: MathUtils.RotatePointAroundTarget(point: D, target: Centroid, radians: radians));
39 public RectangleF BoundingAxisAlignedRectangle
44 X: Math.Min(A.X, Math.Min(B.X, Math.Min(C.X, D.X))),
45 Y: Math.Min(A.Y, Math.Min(B.Y, Math.Min(C.Y, D.Y))));
47 X: Math.Max(A.X, Math.Max(B.X, Math.Max(C.X, D.X))),
48 Y: Math.Max(A.Y, Math.Max(B.Y, Math.Max(C.Y, D.Y))));
49 return new RectangleF(location: min, size: max - min);
53 public bool TryGetEdges(Span<(Vector2 A, Vector2 B)> outputSpan)
55 if (outputSpan.Length < 4) {
return false; }
57 outputSpan[0] = (A, B);
58 outputSpan[1] = (B, C);
59 outputSpan[2] = (C, D);
60 outputSpan[3] = (D, A);
64 public bool Contains(Vector2 point)
69 (Triangle2D triangle1, Triangle2D triangle2)
70 = (
new Triangle2D(A, B, C),
new Triangle2D(A, D, C));
75 if (triangle1.Contains(D) || triangle2.Contains(B))
77 (triangle1, triangle2) = (
new Triangle2D(B, C, D),
new Triangle2D(B, A, D));
80 return triangle1.Contains(point) || triangle2.Contains(point);
83 public bool Intersects(Quad2D other)
85 if (!BoundingAxisAlignedRectangle.Intersects(other.BoundingAxisAlignedRectangle))
90 if (Contains(other.A)) {
return true; }
91 if (Contains(other.B)) {
return true; }
92 if (Contains(other.C)) {
return true; }
93 if (Contains(other.D)) {
return true; }
95 if (other.Contains(A)) {
return true; }
96 if (other.Contains(B)) {
return true; }
97 if (other.Contains(C)) {
return true; }
98 if (other.Contains(D)) {
return true; }
100 Span<(Vector2 A, Vector2 B)> myEdges = stackalloc (Vector2 A, Vector2 B)[4];
101 TryGetEdges(myEdges);
102 Span<(Vector2 A, Vector2 B)> otherEdges = stackalloc (Vector2 A, Vector2 B)[4];
103 other.TryGetEdges(otherEdges);
104 foreach (var edge
in myEdges)
106 foreach (var otherEdge
in otherEdges)
108 if (MathUtils.LineSegmentsIntersect(edge.A, edge.B, otherEdge.A, otherEdge.B)) {
return true; }