| File: Matrix3x2Extensions.cs | Web Access |
| Project: src\src\Graphics\src\Graphics\Graphics.csproj (Microsoft.Maui.Graphics) |
using System; using System.Collections.Generic; using System.Numerics; using System.Text; //[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Microsoft.Maui.Graphics.Tests")] namespace Microsoft.Maui.Graphics { static class Matrix3x2Extensions { public static bool IsZero(this in Matrix3x2 matrix) { if (matrix.M11 != 0) return false; if (matrix.M12 != 0) return false; if (matrix.M21 != 0) return false; if (matrix.M22 != 0) return false; if (matrix.M31 != 0) return false; if (matrix.M32 != 0) return false; return true; } public static bool IsFinite(this in Matrix3x2 matrix) { bool result = true; #if NETSTANDARD2_0 || TIZEN40 result &= !(float.IsNaN(matrix.M11) || float.IsInfinity(matrix.M11)); result &= !(float.IsNaN(matrix.M12) || float.IsInfinity(matrix.M12)); result &= !(float.IsNaN(matrix.M21) || float.IsInfinity(matrix.M21)); result &= !(float.IsNaN(matrix.M22) || float.IsInfinity(matrix.M22)); result &= !(float.IsNaN(matrix.M31) || float.IsInfinity(matrix.M31)); result &= !(float.IsNaN(matrix.M32) || float.IsInfinity(matrix.M32)); #else result &= float.IsFinite(matrix.M11); result &= float.IsFinite(matrix.M12); result &= float.IsFinite(matrix.M21); result &= float.IsFinite(matrix.M22); result &= float.IsFinite(matrix.M31); result &= float.IsFinite(matrix.M32); #endif return result; } public static Vector2 GetScale(this in Matrix3x2 matrix) { var sx = matrix.M12 == 0 ? Math.Abs(matrix.M11) : new Vector2(matrix.M11, matrix.M12).Length(); var sy = matrix.M21 == 0 ? Math.Abs(matrix.M22) : new Vector2(matrix.M21, matrix.M22).Length(); if (matrix.GetDeterminant() < 0) sy = -sy; return new Vector2(sx, sy); } public static float GetRotation(this in Matrix3x2 matrix) { return MathF.Atan2(matrix.M12, matrix.M11); } public static Vector2 GetTranslation(this in Matrix3x2 matrix) { return matrix.Translation; } public static Matrix3x2 WithScale(this Matrix3x2 matrix, Vector2 scale) { var sx = matrix.M12 == 0 ? Math.Abs(matrix.M11) : new Vector2(matrix.M11, matrix.M12).Length(); var sy = matrix.M21 == 0 ? Math.Abs(matrix.M22) : new Vector2(matrix.M21, matrix.M22).Length(); // if (matrix.GetDeterminant() < 0) sy = -sy; scale /= new Vector2(sx, sy); matrix.M11 *= scale.X; matrix.M12 *= scale.X; matrix.M21 *= scale.Y; matrix.M22 *= scale.Y; return matrix; // var t = matrix.Translation; // var r = matrix.GetRotation(); // return CreateMatrix3x2(scale, r, t); } public static Matrix3x2 WithoutScale(this in Matrix3x2 matrix) { return matrix.WithScale(Vector2.One); } public static Matrix3x2 WithRotation(this in Matrix3x2 matrix, float radians) { var t = matrix.Translation; var s = matrix.GetScale(); return CreateMatrix3x2(s, radians, t); } public static Matrix3x2 WithoutRotation(this in Matrix3x2 matrix) { var t = matrix.Translation; var s = matrix.GetScale(); return CreateMatrix3x2(s, 0, t); } public static Matrix3x2 WithTranslation(this Matrix3x2 matrix, Vector2 translation) { matrix.Translation = translation; return matrix; } /// <summary> /// Creates a matrix from an SRT. /// </summary> /// <param name="scale">The scale</param> /// <param name="rotation">The rotation, in radians</param> /// <param name="translation">the translation</param> /// <returns>A Matrix3x2</returns> /// <remarks> /// This is equivalent to:<br/> /// <c> /// m = Matrix3x2.CreateScale(scale)<br/> /// m *= Matri3x2.CreateRotation(rotation)<br/> /// m *= Matri3x2.CreateTranslation(translation)<br/> /// </c> /// </remarks> internal static Matrix3x2 CreateMatrix3x2(Vector2 scale, float rotation, Vector2 translation) { var m = Matrix3x2.CreateRotation(rotation); m.M11 *= scale.X; m.M12 *= scale.X; m.M21 *= scale.Y; m.M22 *= scale.Y; m.M31 = translation.X; m.M32 = translation.Y; return m; } public static float GetLengthScale(this in Matrix3x2 matrix) { var determinant = matrix.GetDeterminant(); var areaScale = MathF.Abs(determinant); return MathF.Sqrt(areaScale); } public static void CopyTo(this in Matrix3x2 matrix, float[] dst, int offset = 0, int count = 6) { count = Math.Min(dst.Length, count); dst[offset + 0] = matrix.M11; dst[offset + 1] = matrix.M12; dst[offset + 2] = matrix.M21; dst[offset + 3] = matrix.M22; if (count > 4) { dst[offset + 4] = matrix.M31; dst[offset + 5] = matrix.M32; } } public static void DeconstructScales(this in Matrix3x2 value, out float scale, out float scalex, out float scaley) { var det = value.GetDeterminant(); scale = MathF.Sqrt(MathF.Abs(det)); scalex = value.M12 == 0 ? MathF.Abs(value.M11) : new Vector2(value.M11, value.M12).Length(); scaley = value.M21 == 0 ? MathF.Abs(value.M22) : new Vector2(value.M21, value.M22).Length(); if (det < 0) scaley = -scaley; } } }