using System; using System.Collections.Generic; using Syntriax.Engine.Core; namespace Syntriax.Engine.Physics2D.Primitives; public record Shape(IList Vertices) { public Vector2D this[Index index] => Vertices[index]; public static Triangle GetSuperTriangle(Shape shape) { float minX = float.MaxValue, minY = float.MaxValue; float maxX = float.MinValue, maxY = float.MinValue; foreach (Vector2D point in shape.Vertices) { minX = MathF.Min(minX, point.X); minY = MathF.Min(minY, point.Y); maxX = MathF.Max(maxX, point.X); maxY = MathF.Max(maxY, point.Y); } float dx = maxX - minX; float dy = maxY - minY; float deltaMax = MathF.Max(dx, dy); float midX = (minX + maxX) / 2; float midY = (minY + maxY) / 2; Vector2D p1 = new((float)midX - 20f * (float)deltaMax, (float)midY - (float)deltaMax); Vector2D p2 = new((float)midX, (float)midY + 20 * (float)deltaMax); Vector2D p3 = new((float)midX + 20 * (float)deltaMax, (float)midY - (float)deltaMax); return new Triangle(p1, p2, p3); } public static void GetLines(Shape shape, IList lines) { lines.Clear(); for (int i = 0; i < shape.Vertices.Count - 1; i++) lines.Add(new(shape.Vertices[i], shape.Vertices[i + 1])); lines.Add(new(shape.Vertices[^1], shape.Vertices[0])); } public static List GetLines(Shape shape) { List lines = new(shape.Vertices.Count - 1); GetLines(shape, lines); return lines; } public static bool ApproximatelyEquals(Shape left, Shape right) { if (left.Vertices.Count != right.Vertices.Count) return false; for (int i = 0; i < left.Vertices.Count; i++) if (!left.Vertices[i].ApproximatelyEquals(right.Vertices[i])) return false; return true; } } public static class ShapeExtensions { public static Triangle ToSuperTriangle(this Shape shape) => Shape.GetSuperTriangle(shape); public static void ToLines(this Shape shape, IList lines) => Shape.GetLines(shape, lines); public static List ToLines(this Shape shape) => Shape.GetLines(shape); public static bool ApproximatelyEquals(this Shape left, Shape right) => Shape.ApproximatelyEquals(left, right); }