diff --git a/SS14.Shared.Maths/UIBox2i.cs b/SS14.Shared.Maths/UIBox2i.cs
index cfcb349cf..d1307ab08 100644
--- a/SS14.Shared.Maths/UIBox2i.cs
+++ b/SS14.Shared.Maths/UIBox2i.cs
@@ -62,6 +62,31 @@ namespace SS14.Shared.Maths
return new UIBox2i(Left + point.X, Top + point.Y, Right + point.X, Bottom + point.Y);
}
+ ///
+ /// Calculates the "intersection" of this and another box.
+ /// Basically, the smallest region that fits in both boxes.
+ ///
+ /// The box to calculate the intersection with.
+ ///
+ /// null if there is no intersection, otherwise the smallest region that fits in both boxes.
+ ///
+ public UIBox2i? Intersection(in UIBox2i other)
+ {
+ if (!Intersects(other))
+ {
+ return null;
+ }
+ return new UIBox2i(
+ Vector2i.ComponentMax(TopLeft, other.TopLeft),
+ Vector2i.ComponentMin(BottomRight, other.BottomRight));
+ }
+
+ public bool Intersects(in UIBox2i other)
+ {
+ return other.Bottom >= this.Top && other.Top <= this.Bottom && other.Right >= this.Left &&
+ other.Left <= this.Right;
+ }
+
// override object.Equals
public override bool Equals(object obj)
{
diff --git a/SS14.UnitTesting/Shared/Maths/UIBox2i_Test.cs b/SS14.UnitTesting/Shared/Maths/UIBox2i_Test.cs
index 46d43508b..bedfe5ec6 100644
--- a/SS14.UnitTesting/Shared/Maths/UIBox2i_Test.cs
+++ b/SS14.UnitTesting/Shared/Maths/UIBox2i_Test.cs
@@ -65,6 +65,15 @@ namespace SS14.UnitTesting.Shared.Maths
10
};
+ private static IEnumerable<(UIBox2i a, UIBox2i b, UIBox2i? expected)> Intersections =>
+ new (UIBox2i, UIBox2i, UIBox2i?)[]
+ {
+ (new UIBox2i(0, 0, 5, 5), new UIBox2i(2, 2, 4, 4), new UIBox2i(2, 2, 4, 4)),
+ (new UIBox2i(0, 0, 5, 5), new UIBox2i(3, 3, 7, 7), new UIBox2i(3, 3, 5, 5)),
+ (new UIBox2i(2, 0, 5, 5), new UIBox2i(0, 3, 4, 7), new UIBox2i(2, 3, 4, 5)),
+ (new UIBox2i(2, 0, 5, 5), new UIBox2i(6, 6, 10, 10), null),
+ };
+
[Test]
public void Box2iVectorConstructor([ValueSource(nameof(Sources))] (int, int, int, int) test)
{
@@ -177,7 +186,8 @@ namespace SS14.UnitTesting.Shared.Maths
}
[Test]
- public void Box2iContains([ValueSource(nameof(SmallTranslations))] (int, int) test)
+ public void Box2iContains([ValueSource(nameof(SmallTranslations))]
+ (int, int) test)
{
var (x, y) = test;
var vec = new Vector2i(x, y);
@@ -190,7 +200,8 @@ namespace SS14.UnitTesting.Shared.Maths
}
[Test]
- public void Box2iNotContains([ValueSource(nameof(LargeTranslations))] (int, int) test)
+ public void Box2iNotContains([ValueSource(nameof(LargeTranslations))]
+ (int, int) test)
{
var (x, y) = test;
var vec = new Vector2i(x, y);
@@ -203,7 +214,8 @@ namespace SS14.UnitTesting.Shared.Maths
}
[Test]
- public void Box2iTranslated([ValueSource(nameof(LargeTranslations))] (int, int) test)
+ public void Box2iTranslated([ValueSource(nameof(LargeTranslations))]
+ (int, int) test)
{
var (x, y) = test;
var vec = new Vector2i(x, y);
@@ -236,5 +248,16 @@ namespace SS14.UnitTesting.Shared.Maths
Assert.That(controlBox.Equals(nullBox), Is.False);
Assert.That(controlBox.Equals(notBox), Is.False);
}
+
+ [Test]
+ public void UIBox2iIntersection(
+ [ValueSource(nameof(Intersections))] (UIBox2i a, UIBox2i b, UIBox2i? expected) value)
+ {
+ var (a, b, expected) = value;
+
+ // This should be a symmetric operation.
+ Assert.That(a.Intersection(b), Is.EqualTo(expected));
+ Assert.That(b.Intersection(a), Is.EqualTo(expected));
+ }
}
}