MatrixTests.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Numerics;
  3. using System.Runtime.InteropServices;
  4. using Avalonia.Media;
  5. using Xunit;
  6. namespace Avalonia.Visuals.UnitTests;
  7. /// <summary>
  8. /// These tests use the "official" Matrix4x4 and Matrix3x2 from the System.Numerics namespace, to validate
  9. /// that Avalonias own implementation of a 3x3 Matrix works correctly.
  10. /// </summary>
  11. public class MatrixTests
  12. {
  13. /// <summary>
  14. /// Because Avalonia is working internally with doubles, but System.Numerics Vector and Matrix implementations
  15. /// only make use of floats, we need to reduce precision, comparing them. It should be sufficient to compare
  16. /// 5 fractional digits to ensure, that the result is correct.
  17. /// </summary>
  18. /// <param name="expected">The expected vector</param>
  19. /// <param name="actual">The actual transformed point</param>
  20. private static void AssertCoordinatesEqualWithReducedPrecision(Vector2 expected, Point actual)
  21. {
  22. double ReducePrecision(double input) => Math.Truncate(input * 10000);
  23. var expectedX = ReducePrecision(expected.X);
  24. var expectedY = ReducePrecision(expected.Y);
  25. var actualX = ReducePrecision(actual.X);
  26. var actualY = ReducePrecision(actual.Y);
  27. Assert.Equal(expectedX, actualX);
  28. Assert.Equal(expectedY, actualY);
  29. }
  30. [Fact]
  31. public void Transform_Point_Should_Return_Correct_Value_For_Translated_Matrix()
  32. {
  33. var vector2 = Vector2.Transform(
  34. new Vector2(1, 1),
  35. Matrix3x2.CreateTranslation(2, 2));
  36. var expected = new Point(vector2.X, vector2.Y);
  37. var matrix = Matrix.CreateTranslation(2, 2);
  38. var point = new Point(1, 1);
  39. var transformedPoint = matrix.Transform(point);
  40. Assert.Equal(expected, transformedPoint);
  41. }
  42. [Fact]
  43. public void Transform_Point_Should_Return_Correct_Value_For_Rotated_Matrix()
  44. {
  45. var expected = Vector2.Transform(
  46. new Vector2(0, 10),
  47. Matrix3x2.CreateRotation((float)Matrix.ToRadians(45)));
  48. var matrix = Matrix.CreateRotation(Matrix.ToRadians(45));
  49. var point = new Point(0, 10);
  50. var actual = matrix.Transform(point);
  51. AssertCoordinatesEqualWithReducedPrecision(expected, actual);
  52. }
  53. [Fact]
  54. public void Transform_Point_Should_Return_Correct_Value_For_Rotate_Matrix_With_Center_Point()
  55. {
  56. var expected = Vector2.Transform(
  57. new Vector2(0, 10),
  58. Matrix3x2.CreateRotation((float)Matrix.ToRadians(30), new Vector2(3, 5)));
  59. var matrix = Matrix.CreateRotation(Matrix.ToRadians(30), new Point(3, 5));
  60. var point = new Point(0, 10);
  61. var actual = matrix.Transform(point);
  62. AssertCoordinatesEqualWithReducedPrecision(expected, actual);
  63. }
  64. [Fact]
  65. public void Transform_Point_Should_Return_Correct_Value_For_Scaled_Matrix()
  66. {
  67. var vector2 = Vector2.Transform(
  68. new Vector2(1, 1),
  69. Matrix3x2.CreateScale(2, 2));
  70. var expected = new Point(vector2.X, vector2.Y);
  71. var matrix = Matrix.CreateScale(2, 2);
  72. var point = new Point(1, 1);
  73. var actual = matrix.Transform(point);
  74. Assert.Equal(expected, actual);
  75. }
  76. [Fact]
  77. public void Transform_Point_Should_Return_Correct_Value_For_Skewed_Matrix()
  78. {
  79. var expected = Vector2.Transform(
  80. new Vector2(1, 1),
  81. Matrix3x2.CreateSkew(30, 20));
  82. var matrix = Matrix.CreateSkew(30, 20);
  83. var point = new Point(1, 1);
  84. var actual = matrix.Transform(point);
  85. AssertCoordinatesEqualWithReducedPrecision(expected, actual);
  86. }
  87. }