using System.ComponentModel.DataAnnotations; using System.Drawing; using System.Numerics; namespace Dashboard { public readonly record struct Box2d(Vector2 Min, Vector2 Max) { public float Left => Min.X; public float Right => Max.X; public float Top => Min.Y; public float Bottom => Max.Y; public Vector2 Size => Max - Min; public Vector2 Center => (Min + Max) * 0.5f; public Box2d(RectangleF rectangle) : this(new Vector2(rectangle.Left, rectangle.Top), new Vector2(rectangle.Right, rectangle.Bottom)) { } public Box2d(float x0, float y0, float x1, float y1) : this(new Vector2(x0, y0), new Vector2(x1, y1)) { } public static Box2d FromPositionAndSize(Vector2 position, Vector2 size, Origin anchor = Origin.Center) { Vector2 half = size * 0.5f; switch (anchor) { case Origin.Center: return new Box2d(position - half, position + half); case Origin.TopLeft: return new Box2d(position, position + size); default: throw new NotImplementedException(); } } public static Box2d Union(Box2d left, Box2d right) { Vector2 min = Vector2.Min(left.Min, right.Min); Vector2 max = Vector2.Max(left.Max, right.Max); return new Box2d(min, max); } public static Box2d Intersect(Box2d left, Box2d right) { Vector2 min = Vector2.Max(left.Min, right.Min); Vector2 max = Vector2.Min(left.Max, right.Max); return new Box2d(min, max); } public static explicit operator RectangleF(Box2d box2d) { return new RectangleF((PointF)box2d.Center, (SizeF)box2d.Size); } public static explicit operator Box2d(RectangleF rectangle) { return new Box2d(rectangle); } } }