From b2759175b6cd6b8d697541214134bb37d1cbb47d Mon Sep 17 00:00:00 2001 From: Andreas Torebring Date: Fri, 26 Aug 2022 13:40:31 +0200 Subject: [PATCH] Rectangle extents are rotated correctly --- .../Math/PrimitivesHelper.cs | 12 ++--- .../Primitives/RectangleFTests.cs | 53 +++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/cs/MonoGame.Extended/Math/PrimitivesHelper.cs b/src/cs/MonoGame.Extended/Math/PrimitivesHelper.cs index 543d23d0..ef151bcb 100644 --- a/src/cs/MonoGame.Extended/Math/PrimitivesHelper.cs +++ b/src/cs/MonoGame.Extended/Math/PrimitivesHelper.cs @@ -65,10 +65,10 @@ namespace MonoGame.Extended // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 4.2; Bounding Volumes - Axis-aligned Bounding Boxes (AABBs). pg 86-87 center = transformMatrix.Transform(center); - halfExtents.X = halfExtents.X * Math.Abs(transformMatrix.M11) + halfExtents.X * Math.Abs(transformMatrix.M12) + - halfExtents.X * Math.Abs(transformMatrix.M31); - halfExtents.Y = halfExtents.Y * Math.Abs(transformMatrix.M21) + halfExtents.Y * Math.Abs(transformMatrix.M22) + - halfExtents.Y * Math.Abs(transformMatrix.M32); + var xRadius = halfExtents.X; + var yRadius = halfExtents.Y; + halfExtents.X = xRadius * Math.Abs(transformMatrix.M11) + yRadius * Math.Abs(transformMatrix.M12); + halfExtents.Y = xRadius * Math.Abs(transformMatrix.M21) + yRadius * Math.Abs(transformMatrix.M22); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -109,7 +109,7 @@ namespace MonoGame.Extended internal static void ClosestPointToPointFromRectangle(Point2 minimum, Point2 maximum, Point2 point, out Point2 result) { // Real-Time Collision Detection, Christer Ericson, 2005. Chapter 5.1.2; Basic Primitive Tests - Closest-point Computations. pg 130-131 - + result = point; // For each coordinate axis, if the point coordinate value is outside box, clamp it to the box, else keep it as is @@ -125,4 +125,4 @@ namespace MonoGame.Extended } } -} \ No newline at end of file +} diff --git a/src/cs/Tests/MonoGame.Extended.Tests/Primitives/RectangleFTests.cs b/src/cs/Tests/MonoGame.Extended.Tests/Primitives/RectangleFTests.cs index 825a685e..9121d6ad 100644 --- a/src/cs/Tests/MonoGame.Extended.Tests/Primitives/RectangleFTests.cs +++ b/src/cs/Tests/MonoGame.Extended.Tests/Primitives/RectangleFTests.cs @@ -77,6 +77,59 @@ namespace MonoGame.Extended.Tests.Primitives Assert.Equal(new Size2(20, 30), result.Size); } + + [Fact] + public void Applies_rotation_and_translation() + { + /* Rectangle with center point aligned in coordinate system with origin 0. + * + * : + * : + * +-+ + * | | + * |p| + * | | + * ...............0-+............ + * : + * : + * : + * + * Rotate center point p, 90 degrees around origin 0. + * + * : + * : + * +---+ + * | p | + * ...........+---0.............. + * : + * : + * : + * + * Then translate rectangle by x=10 and y=20. + * : + * : +---+ + * : | p | + * y=21 - - - - - - - -> +---+ + * . + * : + * ...............0.............. + * : + * : + * : + */ + var rectangle = new RectangleF(new Point2(0, 0), new Size2(2, 4)); + var transform = + Matrix2.CreateRotationZ(MathHelper.PiOver2) + * + Matrix2.CreateTranslation(10, 20); + + var result = RectangleF.Transform(rectangle, ref transform); + + Assert.Equal(-2 + 10, result.Center.X, 6); + Assert.Equal(1 + 20, result.Center.Y, 6); + Assert.Equal(4, result.Size.Width, 6); + Assert.Equal(2, result.Size.Height, 6); + } } } }