using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnitTestSharp; namespace Azimuth.UnitTests { public class MatrixTests : TestFixture { public void CTor_ScaleToo() { Matrix matrix = new Matrix(Math.PI / 4, new Vector(2, -3), 10); Scalar sqrt = Math.Sqrt(2) * 10; CheckEqual(new Vector(2 + sqrt, -3), matrix.TransformPoint(new Vector(1, -1))); } public void CTor() { Matrix matrix = new Matrix(Math.PI / 2, new Vector(10, 20)); CheckEqual(0, matrix.M00); CheckEqual(-1, matrix.M01); CheckEqual(10, matrix.M02); CheckEqual(1, matrix.M10); CheckEqual(0, matrix.M11); CheckEqual(20, matrix.M12); } public void CTor_From2DArray() { var array = new Scalar[,] { { 1, 2, 3 }, { 4, 5, 6} }; var matrix = new Matrix(array); CheckEqual(array[0,0], matrix.M00); CheckEqual(array[0,1], matrix.M01); CheckEqual(array[0,2], matrix.M02); CheckEqual(array[1,0], matrix.M10); CheckEqual(array[1,1], matrix.M11); CheckEqual(array[1,2], matrix.M12); } public void TransformDirection() { Vector vec = new Vector(10, 0); Matrix matrix = new Matrix(Math.PI / 2, new Vector(10, 20)); CheckEqual(new Vector(0, 10), matrix.TransformDirection(vec)); } public void TransformPoint() { Vector vec = new Vector(10, 0); Matrix matrix = new Matrix(Math.PI / 2, new Vector(10, 20)); //Should rotate then translate CheckEqual(new Vector(10, 30), matrix.TransformPoint(vec)); } public void Translation() { Vector point = new Vector(100, -100); Matrix matrix = new Matrix(0, point); CheckEqual(point, matrix.Translation); } public void Determinant() { var array = new Scalar[,] { { 1, 2, 3, }, { 4, 5, 6 } }; Matrix matrix = new Matrix(array); CheckEqual(-3, matrix.Determinant()); } public void Inverse_NotInvertible() { var array = new Scalar[,] { { 1, 2, 4, }, { 16, 32, 64 } }; Matrix forward = new Matrix(array); Matrix backward = forward.Inverse(); Check(Matrix.IsNaN(backward)); } public void Inverse() { var array = new Scalar[,] { { 1, 2, 4, }, { 16, 2, 64 } }; Matrix forward = new Matrix(array); Matrix backward = forward.Inverse(); CheckEqual(Matrix.Identity, forward * backward); CheckEqual(Matrix.Identity, backward * forward); } public void Inverse_TransformPoint() { var array = new Scalar[,] { { 1, 2, 4, }, { 16, 2, 64 } }; Matrix forward = new Matrix(array); Matrix backward = forward.Inverse(); Vector vec = new Vector(8, 2); CheckEqual(vec, forward.TransformPoint(backward.TransformPoint(vec))); CheckEqual(vec, backward.TransformPoint(forward.TransformPoint(vec))); } public void Scalar_Multiplication() { var array = new Scalar[,] { { 1, 2, 3, }, { 4, 5, 6 } }; var doubleArray = new Scalar[,] { { 2, 4, 6, }, { 8, 10, 12 } }; Matrix matrix = new Matrix(array); CheckEqual(new Matrix(doubleArray), matrix * 2); CheckEqual(new Matrix(doubleArray), 2 * matrix); } public void ToString_Test() { var array = new Scalar[,] { { 1, 2, 3, }, { 4, 5, 6 } }; CheckEqual("[ [1 : 2 : 3] : [4 : 5 : 6] ]", new Matrix(array).ToString()); } public void MatrixMultiplication() { var array1 = new Scalar[,] { { 1, 2, 3, }, { 5, 7, 11 }, }; var array2 = new Scalar[,] { {11, 5, 7, }, {3, 1, 2 }, }; var expected1 = new Scalar[,] { { 17, 7, 14, }, { 76, 32, 60 }, }; var expected2 = new Scalar[,] { { 36, 57, 95, }, { 8, 13, 22 }, }; Matrix a = new Matrix(array1); Matrix b = new Matrix(array2); Matrix expectedMatrix1 = new Matrix(expected1); Matrix expectedMatrix2 = new Matrix(expected2); CheckEqual(expectedMatrix1, a * b); CheckEqual(expectedMatrix2, b * a); } public void Negation() { var origin = new Scalar[,] { { 1, 2, 3, }, { 5, 7, 11 }, }; var expectedArray = new Scalar[,] { { -1, -2, -3, }, { -5, -7, -11 }, }; Matrix actual = new Matrix(origin); actual = -actual; Matrix expected = new Matrix(expectedArray); CheckEqual(expected, actual); } public void ArrayAccess() { var actualArray = new Scalar[,] { { 1, 2, 3, }, { 5, 7, 11 }, }; Matrix actualMatrix = new Matrix(actualArray); CheckEqual(actualArray[0, 0], actualMatrix.M00); CheckEqual(actualArray[0, 1], actualMatrix.M01); CheckEqual(actualArray[0, 2], actualMatrix.M02); CheckEqual(actualArray[1, 0], actualMatrix.M10); CheckEqual(actualArray[1, 1], actualMatrix.M11); CheckEqual(actualArray[1, 2], actualMatrix.M12); } public void MatrixMultiplicationOrder() { Matrix orient = new Matrix(Math.PI / 4, Vector.Zero); Matrix translate = new Matrix(0, new Vector(10, -20)); Matrix scale = new Matrix(5, 0, 0, 0, 5, 0); Matrix concat = (translate * orient * scale); Scalar sqrt = Math.Sqrt(2) / 2 * 5; CheckEqual(new Vector(sqrt + 10, sqrt - 20), concat.TransformPoint(Vector.UnitX)); } public void StaticBuildRotation() { CheckEqual(new Matrix(Math.PI / 2, Vector.Zero), Matrix.BuildFromRotation(Math.PI / 2)); } public void StaticBuildTranslation() { CheckEqual(new Matrix(0, Vector.UnitX), Matrix.BuildFromTranslation(Vector.UnitX)); } public void StaticBuildScale() { CheckEqual(new Matrix(0, Vector.Zero, 10), Matrix.BuildFromScale(10)); } public class IsNaN : TestFixture { public void None() { var array = new Scalar[,] { {1, 2, 3}, {4, 5, 6} }; CheckFalse(Matrix.IsNaN(new Matrix(array))); } public void M00() { var array = new Scalar[,] { { Scalar.NaN, 2, 3, }, { 4, 5, 6 }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void M01() { var array = new Scalar[,] { { 1, Scalar.NaN, 3, }, { 4, 5, 6 }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void M02() { var array = new Scalar[,] { { 1, 2, Scalar.NaN, }, { 4, 5, 6 }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void M10() { var array = new Scalar[,] { { 1, 2, 3, }, { Scalar.NaN, 5, 6 }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void M11() { var array = new Scalar[,] { { 1, 2, 3, }, { 4, Scalar.NaN, 6 }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void M12() { var array = new Scalar[,] { { 1, 2, 3, }, { 4, 5, Scalar.NaN }, }; Check(Matrix.IsNaN(new Matrix(array))); } public void All() { var array = new Scalar[,] { { Scalar.NaN, Scalar.NaN, Scalar.NaN, }, { Scalar.NaN, Scalar.NaN, Scalar.NaN }, }; Check(Matrix.IsNaN(new Matrix(array))); } } public class Equality : TestFixture { Matrix a, b; public override void TestSetup() { a = b = new Matrix(0.1, new Vector(0.2, 0.3), 0.7); } public void DifferentTypes() { Scalar c = 0.0; Check(!a.Equals(c)); } public void Equal() { Check(a.Equals(b)); Check(a == b); CheckFalse(a != b); } public void NotEqual_M00() { a.M00 -= 0.001; Check(!a.Equals(b)); Check(a != b); CheckFalse(a == b); } public void NotEqual_M01() { a.M01 -= 0.001; Check(!a.Equals(b)); Check(a != b); CheckFalse(a == b); } public void NotEqual_M02() { a.M02 -= 0.001; Check(!a.Equals(b)); Check(a != b); CheckFalse(a == b); } public void NotEqual_M10() { a.M10 -= 0.001; Check(!a.Equals(b)); Check(a != b); CheckFalse(a == b); } public void NotEqual_M11() { a.M11 -= 0.001; Check(!a.Equals(b)); Check(a != b); CheckFalse(a == b); } public void NotEqual_M12() { a.M12 -= 0.001; Check(a != b); CheckFalse(a == b); Check(!a.Equals(b)); } } } }