MoonTools.Bonk/Bonk/Simplex.cs

109 lines
3.0 KiB
C#
Raw Permalink Normal View History

2020-01-02 04:14:47 +00:00
using System.Collections.Generic;
2019-10-31 23:19:30 +00:00
using System.Numerics;
2019-10-25 19:42:39 +00:00
using MoonTools.Core.Structs;
using System;
2019-10-25 19:42:39 +00:00
namespace MoonTools.Core.Bonk
{
2019-10-25 21:01:36 +00:00
/// <summary>
2019-10-26 05:00:34 +00:00
/// A simplex is a shape with up to n - 2 vertices in the nth dimension.
2019-10-25 21:01:36 +00:00
/// </summary>
2019-12-30 06:19:10 +00:00
public struct Simplex2D : IEquatable<Simplex2D>
2019-10-25 19:42:39 +00:00
{
private Vector2 a;
private Vector2? b;
private Vector2? c;
2019-10-25 19:42:39 +00:00
2019-10-26 05:00:34 +00:00
public Vector2 A => a;
public Vector2? B => b;
public Vector2? C => c;
2019-10-25 20:09:03 +00:00
2019-10-26 05:00:34 +00:00
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;
b = null;
c = null;
2019-10-26 05:00:34 +00:00
}
public Simplex2D(Vector2 a, Vector2 b)
2019-10-25 19:42:39 +00:00
{
2019-10-26 05:00:34 +00:00
this.a = a;
this.b = b;
c = null;
2019-10-25 19:42:39 +00:00
}
2019-10-26 05:00:34 +00:00
public Simplex2D(Vector2 a, Vector2 b, Vector2 c)
2019-10-25 20:09:03 +00:00
{
2019-10-26 05:00:34 +00:00
this.a = a;
this.b = b;
this.c = c;
2019-10-25 20:09:03 +00:00
}
2019-10-25 19:42:39 +00:00
public IEnumerable<Position2D> Vertices
{
get
{
2019-10-26 05:00:34 +00:00
yield return (Position2D)a;
if (b.HasValue) { yield return (Position2D)b; }
if (c.HasValue) { yield return (Position2D)c; }
2019-10-25 19:42:39 +00:00
}
}
2019-10-25 23:20:43 +00:00
public Vector2 Support(Vector2 direction, Transform2D transform)
{
2019-12-16 18:51:27 +00:00
var maxDotProduct = float.NegativeInfinity;
var maxVertex = a;
foreach (var vertex in Vertices)
{
var transformed = Vector2.Transform(vertex, transform.TransformMatrix);
var dot = Vector2.Dot(transformed, direction);
if (dot > maxDotProduct)
{
maxVertex = transformed;
maxDotProduct = dot;
}
}
return maxVertex;
2019-10-25 23:20:43 +00:00
}
public override bool Equals(object obj)
{
2019-12-30 06:19:10 +00:00
return obj is Simplex2D other && Equals(other);
}
public bool Equals(Simplex2D other)
{
2020-01-02 04:14:47 +00:00
if (Count != other.Count) { return false; }
2019-10-25 19:42:39 +00:00
2020-01-02 04:14:47 +00:00
return
(A == other.A && B == other.B && C == other.C) ||
(A == other.A && B == other.C && C == other.B) ||
(A == other.B && B == other.A && C == other.C) ||
(A == other.B && B == other.C && C == other.A) ||
(A == other.C && B == other.A && C == other.B) ||
(A == other.C && B == other.B && C == other.A);
2019-10-25 19:42:39 +00:00
}
2019-10-25 23:20:43 +00:00
public override int GetHashCode()
2019-10-25 19:42:39 +00:00
{
return HashCode.Combine(Vertices);
2019-10-25 19:42:39 +00:00
}
2019-10-26 05:00:34 +00:00
public static bool operator ==(Simplex2D a, Simplex2D b)
2019-10-25 19:42:39 +00:00
{
2019-10-25 23:20:43 +00:00
return a.Equals(b);
}
2019-10-26 05:00:34 +00:00
public static bool operator !=(Simplex2D a, Simplex2D b)
2019-10-25 23:20:43 +00:00
{
return !(a == b);
2019-10-25 19:42:39 +00:00
}
}
2019-12-16 18:51:27 +00:00
}