using System.Linq; using System.Collections.Generic; using System.Numerics; using MoonTools.Core.Structs; using MoreLinq; namespace MoonTools.Core.Bonk { /// /// A simplex is a shape with up to n - 2 vertices in the nth dimension. /// public struct Simplex2D : IShape2D { Vector2 a; Vector2? b; Vector2? c; public Vector2 A => a; public Vector2? B => b; public Vector2? C => c; public bool ZeroSimplex { get { return !b.HasValue && !c.HasValue; } } public bool OneSimplex { get { return b.HasValue && !c.HasValue; } } public bool TwoSimplex { get { return b.HasValue && c.HasValue; } } public int Count => TwoSimplex ? 3 : (OneSimplex ? 2 : 1); public Simplex2D(Vector2 a) { this.a = a; this.b = null; this.c = null; } public Simplex2D(Vector2 a, Vector2 b) { this.a = a; this.b = b; this.c = null; } public Simplex2D(Vector2 a, Vector2 b, Vector2 c) { this.a = a; this.b = b; this.c = c; } public IEnumerable Vertices { get { yield return (Position2D)a; if (b.HasValue) { yield return (Position2D)b; } if (c.HasValue) { yield return (Position2D)c; } } } public AABB AABB(Transform2D transform) { return Bonk.AABB.FromTransformedVertices(Vertices, transform); } public Vector2 Support(Vector2 direction) { return Vertices.MaxBy(vertex => Vector2.Dot(vertex, direction)).First(); } public Vector2 Support(Vector2 direction, Transform2D transform) { return Vector2.Transform(Support(direction), transform.TransformMatrix); } public override bool Equals(object obj) { if (obj is IShape2D other) { return Equals(other); } return false; } public bool Equals(IShape2D other) { if (other is Simplex2D otherSimplex) { if (Count != otherSimplex.Count) { return false; } return Vertices.Intersect(otherSimplex.Vertices).Count() == Count; } return false; } public override int GetHashCode() { var hashCode = -495772172; hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(a); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(b); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(c); hashCode = hashCode * -1521134295 + ZeroSimplex.GetHashCode(); hashCode = hashCode * -1521134295 + OneSimplex.GetHashCode(); hashCode = hashCode * -1521134295 + TwoSimplex.GetHashCode(); hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(Vertices); return hashCode; } public static bool operator ==(Simplex2D a, Simplex2D b) { return a.Equals(b); } public static bool operator !=(Simplex2D a, Simplex2D b) { return !(a == b); } } }