Browse Source

feat: implement Matrix.CreateRotation with center point. (#17657)

Dong Bin 10 months ago
parent
commit
9ef11b030e
2 changed files with 29 additions and 0 deletions
  1. 15 0
      src/Avalonia.Base/Matrix.cs
  2. 14 0
      tests/Avalonia.Base.UnitTests/MatrixTests.cs

+ 15 - 0
src/Avalonia.Base/Matrix.cs

@@ -214,6 +214,21 @@ namespace Avalonia
             return new Matrix(cos, sin, -sin, cos, 0, 0);
         }
 
+        /// <summary>
+        /// Creates a rotation matrix using the given rotation in radians around center point. 
+        /// </summary>
+        /// <param name="radians">The amount of rotation, in radians. </param>
+        /// <param name="center">The location of center point. </param>
+        /// <returns></returns>
+        public static Matrix CreateRotation(double radians, Point center)
+        {
+            var cos = Math.Cos(radians);
+            var sin = Math.Sin(radians);
+            var x = center.X;
+            var y = center.Y;
+            return new Matrix(cos, sin, -sin, cos, x * (1.0 - cos) + y * sin, y * (1.0 - cos) - x * sin);
+        }
+
         /// <summary>
         /// Creates a skew matrix from the given axis skew angles in radians.
         /// </summary>

+ 14 - 0
tests/Avalonia.Base.UnitTests/MatrixTests.cs

@@ -61,6 +61,20 @@ public class MatrixTests
 
         AssertCoordinatesEqualWithReducedPrecision(expected, actual);
     }
+
+    [Fact]
+    public void Transform_Point_Should_Return_Correct_Value_For_Rotate_Matrix_With_Center_Point()
+    {
+        var expected = Vector2.Transform(
+            new Vector2(0, 10), 
+            Matrix3x2.CreateRotation((float)Matrix.ToRadians(30), new Vector2(3, 5)));
+
+        var matrix = Matrix.CreateRotation(Matrix.ToRadians(30), new Point(3, 5));
+        var point = new Point(0, 10);
+        var actual = matrix.Transform(point);
+
+        AssertCoordinatesEqualWithReducedPrecision(expected, actual);
+    }
     
     [Fact]
     public void Transform_Point_Should_Return_Correct_Value_For_Scaled_Matrix()