// Copyright (c) 2010-2014 SharpDX - Alexandre Mutel // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE.using System; using System; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SharpDX.Mathematics.Interop; namespace SharpDX { /// /// Direct2D Matrix3x2. Supports implicit cast from . /// [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct Matrix3x2 { /// /// Gets the identity matrix. /// /// The identity matrix. public readonly static Matrix3x2 Identity = new Matrix3x2(1, 0, 0, 1, 0, 0); /// /// Element (1,1) /// public float M11; /// /// Element (1,2) /// public float M12; /// /// Element (2,1) /// public float M21; /// /// Element (2,2) /// public float M22; /// /// Element (3,1) /// public float M31; /// /// Element (3,2) /// public float M32; /// /// Initializes a new instance of the struct. /// /// The value that will be assigned to all components. public Matrix3x2(float value) { M11 = M12 = M21 = M22 = M31 = M32 = value; } /// /// Initializes a new instance of the struct. /// /// The value to assign at row 1 column 1 of the matrix. /// The value to assign at row 1 column 2 of the matrix. /// The value to assign at row 2 column 1 of the matrix. /// The value to assign at row 2 column 2 of the matrix. /// The value to assign at row 3 column 1 of the matrix. /// The value to assign at row 3 column 2 of the matrix. public Matrix3x2(float M11, float M12, float M21, float M22, float M31, float M32) { this.M11 = M11; this.M12 = M12; this.M21 = M21; this.M22 = M22; this.M31 = M31; this.M32 = M32; } /// /// Initializes a new instance of the struct. /// /// The values to assign to the components of the matrix. This must be an array with six elements. /// Thrown when is null. /// Thrown when contains more or less than six elements. public Matrix3x2(float[] values) { if (values == null) throw new ArgumentNullException("values"); if (values.Length != 6) throw new ArgumentOutOfRangeException("values", "There must be six input values for Matrix3x2."); M11 = values[0]; M12 = values[1]; M21 = values[2]; M22 = values[3]; M31 = values[4]; M32 = values[5]; } /// /// Gets or sets the first row in the matrix; that is M11 and M12. /// public Vector2 Row1 { get { return new Vector2(M11, M12); } set { M11 = value.X; M12 = value.Y; } } /// /// Gets or sets the second row in the matrix; that is M21 and M22. /// public Vector2 Row2 { get { return new Vector2(M21, M22); } set { M21 = value.X; M22 = value.Y; } } /// /// Gets or sets the third row in the matrix; that is M31 and M32. /// public Vector2 Row3 { get { return new Vector2(M31, M32); } set { M31 = value.X; M32 = value.Y; } } /// /// Gets or sets the first column in the matrix; that is M11, M21, and M31. /// public Vector3 Column1 { get { return new Vector3(M11, M21, M31); } set { M11 = value.X; M21 = value.Y; M31 = value.Z; } } /// /// Gets or sets the second column in the matrix; that is M12, M22, and M32. /// public Vector3 Column2 { get { return new Vector3(M12, M22, M32); } set { M12 = value.X; M22 = value.Y; M32 = value.Z;} } /// /// Gets or sets the translation of the matrix; that is M31 and M32. /// public Vector2 TranslationVector { get { return new Vector2(M31, M32); } set { M31 = value.X; M32 = value.Y; } } /// /// Gets or sets the scale of the matrix; that is M11 and M22. /// public Vector2 ScaleVector { get { return new Vector2(M11, M22); } set { M11 = value.X; M22 = value.Y; } } /// /// Gets a value indicating whether this instance is an identity matrix. /// /// /// true if this instance is an identity matrix; otherwise, false. /// public bool IsIdentity { get { return this.Equals(Identity); } } /// /// Gets or sets the component at the specified index. /// /// The value of the matrix component, depending on the index. /// The zero-based index of the component to access. /// The value of the component at the specified index. /// Thrown when the is out of the range [0, 5]. public float this[int index] { get { switch (index) { case 0: return M11; case 1: return M12; case 2: return M21; case 3: return M22; case 4: return M31; case 5: return M32; } throw new ArgumentOutOfRangeException("index", "Indices for Matrix3x2 run from 0 to 5, inclusive."); } set { switch (index) { case 0: M11 = value; break; case 1: M12 = value; break; case 2: M21 = value; break; case 3: M22 = value; break; case 4: M31 = value; break; case 5: M32 = value; break; default: throw new ArgumentOutOfRangeException("index", "Indices for Matrix3x2 run from 0 to 5, inclusive."); } } } /// /// Gets or sets the component at the specified index. /// /// The value of the matrix component, depending on the index. /// The row of the matrix to access. /// The column of the matrix to access. /// The value of the component at the specified index. /// Thrown when the or is out of the range [0, 3]. public float this[int row, int column] { get { if (row < 0 || row > 2) throw new ArgumentOutOfRangeException("row", "Rows and columns for matrices run from 0 to 2, inclusive."); if (column < 0 || column > 1) throw new ArgumentOutOfRangeException("column", "Rows and columns for matrices run from 0 to 1, inclusive."); return this[(row * 2) + column]; } set { if (row < 0 || row > 2) throw new ArgumentOutOfRangeException("row", "Rows and columns for matrices run from 0 to 2, inclusive."); if (column < 0 || column > 1) throw new ArgumentOutOfRangeException("column", "Rows and columns for matrices run from 0 to 1, inclusive."); this[(row * 2) + column] = value; } } /// /// Creates an array containing the elements of the matrix. /// /// A sixteen-element array containing the components of the matrix. public float[] ToArray() { return new[] { M11, M12, M21, M22, M31, M32 }; } /// /// Determines the sum of two matrices. /// /// The first matrix to add. /// The second matrix to add. /// When the method completes, contains the sum of the two matrices. public static void Add(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) { result.M11 = left.M11 + right.M11; result.M12 = left.M12 + right.M12; result.M21 = left.M21 + right.M21; result.M22 = left.M22 + right.M22; result.M31 = left.M31 + right.M31; result.M32 = left.M32 + right.M32; } /// /// Determines the sum of two matrices. /// /// The first matrix to add. /// The second matrix to add. /// The sum of the two matrices. public static Matrix3x2 Add(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Add(ref left, ref right, out result); return result; } /// /// Determines the difference between two matrices. /// /// The first matrix to subtract. /// The second matrix to subtract. /// When the method completes, contains the difference between the two matrices. public static void Subtract(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) { result.M11 = left.M11 - right.M11; result.M12 = left.M12 - right.M12; result.M21 = left.M21 - right.M21; result.M22 = left.M22 - right.M22; result.M31 = left.M31 - right.M31; result.M32 = left.M32 - right.M32; } /// /// Determines the difference between two matrices. /// /// The first matrix to subtract. /// The second matrix to subtract. /// The difference between the two matrices. public static Matrix3x2 Subtract(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Subtract(ref left, ref right, out result); return result; } /// /// Scales a matrix by the given value. /// /// The matrix to scale. /// The amount by which to scale. /// When the method completes, contains the scaled matrix. public static void Multiply(ref Matrix3x2 left, float right, out Matrix3x2 result) { result.M11 = left.M11 * right; result.M12 = left.M12 * right; result.M21 = left.M21 * right; result.M22 = left.M22 * right; result.M31 = left.M31 * right; result.M32 = left.M32 * right; } /// /// Scales a matrix by the given value. /// /// The matrix to scale. /// The amount by which to scale. /// The scaled matrix. public static Matrix3x2 Multiply(Matrix3x2 left, float right) { Matrix3x2 result; Multiply(ref left, right, out result); return result; } /// /// Determines the product of two matrices. /// /// The first matrix to multiply. /// The second matrix to multiply. /// The product of the two matrices. public static void Multiply(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) { Matrix3x2 temp = new Matrix3x2(); temp.M11 = (left.M11 * right.M11) + (left.M12 * right.M21); temp.M12 = (left.M11 * right.M12) + (left.M12 * right.M22); temp.M21 = (left.M21 * right.M11) + (left.M22 * right.M21); temp.M22 = (left.M21 * right.M12) + (left.M22 * right.M22); temp.M31 = (left.M31 * right.M11) + (left.M32 * right.M21) + right.M31; temp.M32 = (left.M31 * right.M12) + (left.M32 * right.M22) + right.M32; result = temp; } /// /// Determines the product of two matrices. /// /// The first matrix to multiply. /// The second matrix to multiply. /// The product of the two matrices. public static Matrix3x2 Multiply(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Multiply(ref left, ref right, out result); return result; } /// /// Scales a matrix by the given value. /// /// The matrix to scale. /// The amount by which to scale. /// When the method completes, contains the scaled matrix. public static void Divide(ref Matrix3x2 left, float right, out Matrix3x2 result) { float inv = 1.0f / right; result.M11 = left.M11 * inv; result.M12 = left.M12 * inv; result.M21 = left.M21 * inv; result.M22 = left.M22 * inv; result.M31 = left.M31 * inv; result.M32 = left.M32 * inv; } /// /// Determines the quotient of two matrices. /// /// The first matrix to divide. /// The second matrix to divide. /// When the method completes, contains the quotient of the two matrices. public static void Divide(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) { result.M11 = left.M11 / right.M11; result.M12 = left.M12 / right.M12; result.M21 = left.M21 / right.M21; result.M22 = left.M22 / right.M22; result.M31 = left.M31 / right.M31; result.M32 = left.M32 / right.M32; } /// /// Negates a matrix. /// /// The matrix to be negated. /// When the method completes, contains the negated matrix. public static void Negate(ref Matrix3x2 value, out Matrix3x2 result) { result.M11 = -value.M11; result.M12 = -value.M12; result.M21 = -value.M21; result.M22 = -value.M22; result.M31 = -value.M31; result.M32 = -value.M32; } /// /// Negates a matrix. /// /// The matrix to be negated. /// The negated matrix. public static Matrix3x2 Negate(Matrix3x2 value) { Matrix3x2 result; Negate(ref value, out result); return result; } /// /// Performs a linear interpolation between two matrices. /// /// Start matrix. /// End matrix. /// Value between 0 and 1 indicating the weight of . /// When the method completes, contains the linear interpolation of the two matrices. /// /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. /// public static void Lerp(ref Matrix3x2 start, ref Matrix3x2 end, float amount, out Matrix3x2 result) { result.M11 = MathUtil.Lerp(start.M11, end.M11, amount); result.M12 = MathUtil.Lerp(start.M12, end.M12, amount); result.M21 = MathUtil.Lerp(start.M21, end.M21, amount); result.M22 = MathUtil.Lerp(start.M22, end.M22, amount); result.M31 = MathUtil.Lerp(start.M31, end.M31, amount); result.M32 = MathUtil.Lerp(start.M32, end.M32, amount); } /// /// Performs a linear interpolation between two matrices. /// /// Start matrix. /// End matrix. /// Value between 0 and 1 indicating the weight of . /// The linear interpolation of the two matrices. /// /// Passing a value of 0 will cause to be returned; a value of 1 will cause to be returned. /// public static Matrix3x2 Lerp(Matrix3x2 start, Matrix3x2 end, float amount) { Matrix3x2 result; Lerp(ref start, ref end, amount, out result); return result; } /// /// Performs a cubic interpolation between two matrices. /// /// Start matrix. /// End matrix. /// Value between 0 and 1 indicating the weight of . /// When the method completes, contains the cubic interpolation of the two matrices. public static void SmoothStep(ref Matrix3x2 start, ref Matrix3x2 end, float amount, out Matrix3x2 result) { amount = MathUtil.SmoothStep(amount); Lerp(ref start, ref end, amount, out result); } /// /// Performs a cubic interpolation between two matrices. /// /// Start matrix. /// End matrix. /// Value between 0 and 1 indicating the weight of . /// The cubic interpolation of the two matrices. public static Matrix3x2 SmoothStep(Matrix3x2 start, Matrix3x2 end, float amount) { Matrix3x2 result; SmoothStep(ref start, ref end, amount, out result); return result; } /// /// Creates a matrix that scales along the x-axis and y-axis. /// /// Scaling factor for both axes. /// When the method completes, contains the created scaling matrix. public static void Scaling(ref Vector2 scale, out Matrix3x2 result) { Scaling(scale.X, scale.Y, out result); } /// /// Creates a matrix that scales along the x-axis and y-axis. /// /// Scaling factor for both axes. /// The created scaling matrix. public static Matrix3x2 Scaling(Vector2 scale) { Matrix3x2 result; Scaling(ref scale, out result); return result; } /// /// Creates a matrix that scales along the x-axis and y-axis. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// When the method completes, contains the created scaling matrix. public static void Scaling(float x, float y, out Matrix3x2 result) { result = Matrix3x2.Identity; result.M11 = x; result.M22 = y; } /// /// Creates a matrix that scales along the x-axis and y-axis. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// The created scaling matrix. public static Matrix3x2 Scaling(float x, float y) { Matrix3x2 result; Scaling(x, y, out result); return result; } /// /// Creates a matrix that uniformly scales along both axes. /// /// The uniform scale that is applied along both axes. /// When the method completes, contains the created scaling matrix. public static void Scaling(float scale, out Matrix3x2 result) { result = Matrix3x2.Identity; result.M11 = result.M22 = scale; } /// /// Creates a matrix that uniformly scales along both axes. /// /// The uniform scale that is applied along both axes. /// The created scaling matrix. public static Matrix3x2 Scaling(float scale) { Matrix3x2 result; Scaling(scale, out result); return result; } /// /// Creates a matrix that is scaling from a specified center. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// The center of the scaling. /// The created scaling matrix. public static Matrix3x2 Scaling(float x, float y, Vector2 center) { Matrix3x2 result; result.M11 = x; result.M12 = 0.0f; result.M21 = 0.0f; result.M22 = y; result.M31 = center.X - (x * center.X); result.M32 = center.Y - (y * center.Y); return result; } /// /// Creates a matrix that is scaling from a specified center. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// The center of the scaling. /// The created scaling matrix. public static void Scaling( float x, float y, ref Vector2 center, out Matrix3x2 result) { Matrix3x2 localResult; localResult.M11 = x; localResult.M12 = 0.0f; localResult.M21 = 0.0f; localResult.M22 = y; localResult.M31 = center.X - (x * center.X); localResult.M32 = center.Y - (y * center.Y); result = localResult; } /// /// Calculates the determinant of this matrix. /// /// Result of the determinant. public float Determinant() { return (M11 * M22) - (M12 * M21); } /// /// Creates a matrix that rotates. /// /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis. /// When the method completes, contains the created rotation matrix. public static void Rotation(float angle, out Matrix3x2 result) { float cos = (float)Math.Cos(angle); float sin = (float)Math.Sin(angle); result = Matrix3x2.Identity; result.M11 = cos; result.M12 = sin; result.M21 = -sin; result.M22 = cos; } /// /// Creates a matrix that rotates. /// /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis. /// The created rotation matrix. public static Matrix3x2 Rotation(float angle) { Matrix3x2 result; Rotation(angle, out result); return result; } /// /// Creates a matrix that rotates about a specified center. /// /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis. /// The center of the rotation. /// The created rotation matrix. public static Matrix3x2 Rotation(float angle, Vector2 center) { Matrix3x2 result; Rotation(angle, center, out result); return result; } /// /// Creates a matrix that rotates about a specified center. /// /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis. /// The center of the rotation. /// When the method completes, contains the created rotation matrix. public static void Rotation(float angle, Vector2 center, out Matrix3x2 result) { result = Translation(-center) * Rotation(angle) * Translation(center); } /// /// Creates a transformation matrix. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis. /// X-coordinate offset. /// Y-coordinate offset. /// When the method completes, contains the created transformation matrix. public static void Transformation(float xScale, float yScale, float angle, float xOffset, float yOffset, out Matrix3x2 result) { result = Scaling(xScale, yScale) * Rotation(angle) * Translation(xOffset, yOffset); } /// /// Creates a transformation matrix. /// /// Scaling factor that is applied along the x-axis. /// Scaling factor that is applied along the y-axis. /// Angle of rotation in radians. /// X-coordinate offset. /// Y-coordinate offset. /// The created transformation matrix. public static Matrix3x2 Transformation(float xScale, float yScale, float angle, float xOffset, float yOffset) { Matrix3x2 result; Transformation(xScale, yScale, angle, xOffset, yOffset, out result); return result; } /// /// Creates a translation matrix using the specified offsets. /// /// The offset for both coordinate planes. /// When the method completes, contains the created translation matrix. public static void Translation(ref Vector2 value, out Matrix3x2 result) { Translation(value.X, value.Y, out result); } /// /// Creates a translation matrix using the specified offsets. /// /// The offset for both coordinate planes. /// The created translation matrix. public static Matrix3x2 Translation(Vector2 value) { Matrix3x2 result; Translation(ref value, out result); return result; } /// /// Creates a translation matrix using the specified offsets. /// /// X-coordinate offset. /// Y-coordinate offset. /// When the method completes, contains the created translation matrix. public static void Translation(float x, float y, out Matrix3x2 result) { result = Matrix3x2.Identity; result.M31 = x; result.M32 = y; } /// /// Creates a translation matrix using the specified offsets. /// /// X-coordinate offset. /// Y-coordinate offset. /// The created translation matrix. public static Matrix3x2 Translation(float x, float y) { Matrix3x2 result; Translation(x, y, out result); return result; } /// /// Transforms a vector by this matrix. /// /// The matrix to use as a transformation matrix. /// The original vector to apply the transformation. /// The result of the transformation for the input vector. public static Vector2 TransformPoint(Matrix3x2 matrix, Vector2 point) { Vector2 result; result.X = (point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.M31; result.Y = (point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.M32; return result; } /// /// Transforms a vector by this matrix. /// /// The matrix to use as a transformation matrix. /// The original vector to apply the transformation. /// The result of the transformation for the input vector. /// public static void TransformPoint(ref Matrix3x2 matrix, ref Vector2 point, out Vector2 result) { Vector2 localResult; localResult.X = (point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.M31; localResult.Y = (point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.M32; result = localResult; } /// /// Calculates the inverse of this matrix instance. /// public void Invert() { Invert(ref this, out this); } /// /// Calculates the inverse of the specified matrix. /// /// The matrix whose inverse is to be calculated. /// the inverse of the specified matrix. public static Matrix3x2 Invert(Matrix3x2 value) { Matrix3x2 result; Invert(ref value, out result); return result; } /// /// Creates a skew matrix. /// /// Angle of skew along the X-axis in radians. /// Angle of skew along the Y-axis in radians. /// The created skew matrix. public static Matrix3x2 Skew(float angleX, float angleY) { Matrix3x2 result; Skew(angleX, angleY, out result); return result; } /// /// Creates a skew matrix. /// /// Angle of skew along the X-axis in radians. /// Angle of skew along the Y-axis in radians. /// When the method completes, contains the created skew matrix. public static void Skew(float angleX, float angleY, out Matrix3x2 result) { result = Matrix.Identity; result.M12 = (float) Math.Tan(angleX); result.M21 = (float) Math.Tan(angleY); } /// /// Calculates the inverse of the specified matrix. /// /// The matrix whose inverse is to be calculated. /// When the method completes, contains the inverse of the specified matrix. public static void Invert(ref Matrix3x2 value, out Matrix3x2 result) { float determinant = value.Determinant(); if (MathUtil.IsZero(determinant)) { result = Identity; return; } float invdet = 1.0f / determinant; float _offsetX = value.M31; float _offsetY = value.M32; result = new Matrix3x2( value.M22 * invdet, -value.M12 * invdet, -value.M21 * invdet, value.M11 * invdet, (value.M21 * _offsetY - _offsetX * value.M22) * invdet, (_offsetX * value.M12 - value.M11 * _offsetY) * invdet); } /// /// Adds two matrices. /// /// The first matrix to add. /// The second matrix to add. /// The sum of the two matrices. public static Matrix3x2 operator +(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Add(ref left, ref right, out result); return result; } /// /// Assert a matrix (return it unchanged). /// /// The matrix to assert (unchanged). /// The asserted (unchanged) matrix. public static Matrix3x2 operator +(Matrix3x2 value) { return value; } /// /// Subtracts two matrices. /// /// The first matrix to subtract. /// The second matrix to subtract. /// The difference between the two matrices. public static Matrix3x2 operator -(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Subtract(ref left, ref right, out result); return result; } /// /// Negates a matrix. /// /// The matrix to negate. /// The negated matrix. public static Matrix3x2 operator -(Matrix3x2 value) { Matrix3x2 result; Negate(ref value, out result); return result; } /// /// Scales a matrix by a given value. /// /// The matrix to scale. /// The amount by which to scale. /// The scaled matrix. public static Matrix3x2 operator *(float left, Matrix3x2 right) { Matrix3x2 result; Multiply(ref right, left, out result); return result; } /// /// Scales a matrix by a given value. /// /// The matrix to scale. /// The amount by which to scale. /// The scaled matrix. public static Matrix3x2 operator *(Matrix3x2 left, float right) { Matrix3x2 result; Multiply(ref left, right, out result); return result; } /// /// Multiplies two matrices. /// /// The first matrix to multiply. /// The second matrix to multiply. /// The product of the two matrices. public static Matrix3x2 operator *(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Multiply(ref left, ref right, out result); return result; } /// /// Scales a matrix by a given value. /// /// The matrix to scale. /// The amount by which to scale. /// The scaled matrix. public static Matrix3x2 operator /(Matrix3x2 left, float right) { Matrix3x2 result; Divide(ref left, right, out result); return result; } /// /// Divides two matrices. /// /// The first matrix to divide. /// The second matrix to divide. /// The quotient of the two matrices. public static Matrix3x2 operator /(Matrix3x2 left, Matrix3x2 right) { Matrix3x2 result; Divide(ref left, ref right, out result); return result; } /// /// Tests for equality between two objects. /// /// The first value to compare. /// The second value to compare. /// true if has the same value as ; otherwise, false. [MethodImpl((MethodImplOptions)0x100)] // MethodImplOptions.AggressiveInlining public static bool operator ==(Matrix3x2 left, Matrix3x2 right) { return left.Equals(ref right); } /// /// Tests for inequality between two objects. /// /// The first value to compare. /// The second value to compare. /// true if has a different value than ; otherwise, false. [MethodImpl((MethodImplOptions)0x100)] // MethodImplOptions.AggressiveInlining public static bool operator !=(Matrix3x2 left, Matrix3x2 right) { return !left.Equals(ref right); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { return string.Format(CultureInfo.CurrentCulture, "[M11:{0} M12:{1}] [M21:{2} M22:{3}] [M31:{4} M32:{5}]", M11, M12, M21, M22, M31, M32); } /// /// Returns a that represents this instance. /// /// The format. /// /// A that represents this instance. /// public string ToString(string format) { if (format == null) return ToString(); return string.Format(format, CultureInfo.CurrentCulture, "[M11:{0} M12:{1}] [M21:{2} M22:{3}] [M31:{4} M32:{5}]", M11.ToString(format, CultureInfo.CurrentCulture), M12.ToString(format, CultureInfo.CurrentCulture), M21.ToString(format, CultureInfo.CurrentCulture), M22.ToString(format, CultureInfo.CurrentCulture), M31.ToString(format, CultureInfo.CurrentCulture), M32.ToString(format, CultureInfo.CurrentCulture)); } /// /// Returns a that represents this instance. /// /// The format provider. /// /// A that represents this instance. /// public string ToString(IFormatProvider formatProvider) { return string.Format(formatProvider, "[M11:{0} M12:{1}] [M21:{2} M22:{3}] [M31:{4} M32:{5}]", M11.ToString(formatProvider), M12.ToString(formatProvider), M21.ToString(formatProvider), M22.ToString(formatProvider), M31.ToString(formatProvider), M32.ToString(formatProvider)); } /// /// Returns a that represents this instance. /// /// The format. /// The format provider. /// /// A that represents this instance. /// public string ToString(string format, IFormatProvider formatProvider) { if (format == null) return ToString(formatProvider); return string.Format(format, formatProvider, "[M11:{0} M12:{1}] [M21:{2} M22:{3}] [M31:{4} M32:{5}]", M11.ToString(format, formatProvider), M12.ToString(format, formatProvider), M21.ToString(format, formatProvider), M22.ToString(format, formatProvider), M31.ToString(format, formatProvider), M32.ToString(format, formatProvider)); } /// /// Returns a hash code for this instance. /// /// /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. /// public override int GetHashCode() { unchecked { var hashCode = M11.GetHashCode(); hashCode = (hashCode * 397) ^ M12.GetHashCode(); hashCode = (hashCode * 397) ^ M21.GetHashCode(); hashCode = (hashCode * 397) ^ M22.GetHashCode(); hashCode = (hashCode * 397) ^ M31.GetHashCode(); hashCode = (hashCode * 397) ^ M32.GetHashCode(); return hashCode; } } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public bool Equals(ref Matrix3x2 other) { return (MathUtil.NearEqual(other.M11, M11) && MathUtil.NearEqual(other.M12, M12) && MathUtil.NearEqual(other.M21, M21) && MathUtil.NearEqual(other.M22, M22) && MathUtil.NearEqual(other.M31, M31) && MathUtil.NearEqual(other.M32, M32)); } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// [MethodImpl((MethodImplOptions)0x100)] // MethodImplOptions.AggressiveInlining public bool Equals(Matrix3x2 other) { return Equals(ref other); } /// /// Determines whether the specified is equal to this instance. /// /// The to compare with this instance. /// /// true if the specified is equal to this instance; otherwise, false. /// public override bool Equals(object value) { if (!(value is Matrix3x2)) return false; var strongValue = (Matrix3x2)value; return Equals(ref strongValue); } /// /// Performs an implicit conversion from to . /// /// The matrix. /// The result of the conversion. public static implicit operator Matrix3x2(Matrix matrix) { return new Matrix3x2 { M11 = matrix.M11, M12 = matrix.M12, M21 = matrix.M21, M22 = matrix.M22, M31 = matrix.M41, M32 = matrix.M42 }; } /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public unsafe static implicit operator RawMatrix3x2(Matrix3x2 value) { return *(RawMatrix3x2*)&value; } /// /// Performs an implicit conversion from to . /// /// The value. /// The result of the conversion. public unsafe static implicit operator Matrix3x2(RawMatrix3x2 value) { return *(Matrix3x2*)&value; } } }