using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using UnitTestSharp; namespace Azimuth.UnitTests { public class VectorTests : TestFixture { public class IVectorSpaceTests : TestFixture { public void Dimension() { IVectorSpace v1 = new Vector(4, 14); CheckEqual(2, v1.Dimension); } public void GetDimension() { IVectorSpace v1 = new Vector(4, 14); CheckEqual(4, v1[0]); CheckEqual(14, v1[1]); } public void GetDimension_OutOfBounds_Hi() { IVectorSpace v1 = new Vector(4, 14); CheckThrow(typeof(System.Exception)); Scalar dummy = v1[2]; CheckFalse(dummy == 0); //dummy } public void GetDimension_OutOfBounds_Lo() { IVectorSpace v1 = new Vector(4, 14); CheckThrow(typeof(System.Exception)); Scalar dummy = v1[-1]; CheckFalse(dummy == 0); //dummy } public void AssignmentAdd() { IVectorSpace a = new Vector(-10, 10); Vector b = new Vector(5, -5); a.AddAssignment(b); CheckEqual(new Vector(-5, 5), a); } public void AssignmentSubtract() { IVectorSpace a = new Vector(-10, 10); Vector b = new Vector(5, -5); a.SubtractAssignment(b); CheckEqual(new Vector(-15, 15), a); } public void AssignmentScale() { IVectorSpace a = new Vector(-10, 10); Scalar b = -2; a.ScaleAssignment(b); CheckEqual(new Vector(20, -20), a); } public void AssignmentScaleThenAdd() { IVectorSpace a = new Vector(10, 20); Scalar scale = 10; Vector b = new Vector(1, -1); a.ScaleThenAddAssignment(scale, b); CheckEqual(new Vector(20, 10), a); CheckEqual(new Vector(1, -1), b); } public void InnerProduct() { Vector a = new Vector(-10, 10); Vector b = new Vector(10, -10); CheckEqual(-200, a.InnerProduct(b)); CheckEqual(new Vector(-10, 10), a); CheckEqual(new Vector(10, -10), b); } public void Clone() { Vector a = new Vector(10, 20); Vector b = ((IVectorSpace)a).Clone(); a += new Vector(1, 1); CheckEqual(new Vector(10, 20), b); CheckEqual(new Vector(11, 21), a); } } public void Ctor() { Vector vec = new Vector(17, 23); CheckEqual(17, vec.X); CheckEqual(23, vec.Y); } public void StaticBuilder_AngleMag() { Vector vec = Vector.BuildFromAngleMagnitude(Math.PI / 2.0, 50); CheckEqual(0, vec.X); CheckEqual(50, vec.Y); } public void StaticBuilder_XY() { Vector vec = Vector.BuildFromXY(17, 23); CheckEqual(17, vec.X); CheckEqual(23, vec.Y); } public void StaticDotProduct() { Vector v1 = new Vector(17, 23); Vector v2 = new Vector(-23, 17); CheckEqual(0, Vector.DotProduct(v1, v2)); CheckEqual(0, Vector.DotProduct(v2, v1)); } public void DotProduct() { Vector v1 = new Vector(17, 23); Vector v2 = new Vector(-23, 17); CheckEqual(0, v1.DotProduct(v2)); CheckEqual(0, v2.DotProduct(v1)); } public void StaticCrossProduct() { Vector v1 = new Vector(5, 11); Vector v2 = new Vector(-11, 17); CheckEqual(206, Vector.CrossProduct(v1, v2)); CheckEqual(-206, Vector.CrossProduct(v2, v1)); } public void CrossProduct() { Vector v1 = new Vector(5, 11); Vector v2 = new Vector(-11, 17); CheckEqual(206, v1.CrossProduct(v2)); CheckEqual(-206, v2.CrossProduct(v1)); } public void LengthSquared() { Vector v1 = new Vector(17, 23); CheckEqual(818, v1.LengthSquared()); } public void Length() { Vector v1 = new Vector(3, 4); CheckEqual(5, v1.Length()); } public void Length_Zero() { Vector v1 = new Vector(0, 0); CheckEqual(0, v1.Length()); } public void Length_Negative_Low() { Vector v1 = new Vector(-3, 4); CheckEqual(5, v1.Length()); } public void Length_Negative_High() { Vector v1 = new Vector(3, -4); CheckEqual(5, v1.Length()); } public void Length_AllNegative() { Vector v1 = new Vector(-3, -4); CheckEqual(5, v1.Length()); } public void Length_XCancellation() { Vector v1 = new Vector(0, -4); CheckEqual(4, v1.Length()); } public void Length_YCancellation() { Vector v1 = new Vector(-3, 0); CheckEqual(3, v1.Length()); } public void DistanceSquared() { Vector v1 = new Vector(11, 13); Vector v2 = new Vector(28, 36); CheckEqual(818, Vector.DistanceSquared(v1, v2)); CheckEqual(818, Vector.DistanceSquared(v2, v1)); } public void Distance() { Vector v1 = new Vector(11, 13); Vector v2 = new Vector(15, 16); CheckEqual(5, Vector.Distance(v2, v1)); } public void Equality() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(3, 4); CheckEqual(v1, v2); } public void FuzzyEquality() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(3 + 1e-11, 4 - 1e-11); CheckEqual(v1, v2); } public void IsSameDirection() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI, 1); Vector v2 = Vector.BuildFromAngleMagnitude(Math.PI, 100); Check(Vector.IsSameDirection(v1, v2)); } public void IsSameDirection_Fuzzy() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI, 1); Vector v2 = Vector.BuildFromAngleMagnitude(Math.PI + 1e-20, 100); Check(Vector.IsSameDirection(v1, v2)); } public void IsSameMagnitude() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 1000); Vector v2 = new Vector(1000, 0); Check(Vector.IsSameMagnitude(v1, v2)); } public void IsSameMagnitude_Fuzzy() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 1000 + 1e-11); Vector v2 = new Vector(1000, 0); Check(Vector.IsSameMagnitude(v1, v2)); } public void IsSameDirectionAndMagnitude_Fuzzy() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 1000 + 1e-11); Vector v2 = Vector.BuildFromAngleMagnitude(Math.PI / 4 + 1e-20, 1000); Check(Vector.IsSameDirectionAndMagnitude(v1, v2)); } public void Negation() { Vector v1 = new Vector(-17, 23); CheckEqual(17, (-v1).X); CheckEqual(-23, (-v1).Y); } public void Scaling_InPlace() { Vector v1 = new Vector(1, 2); v1 *= 3; CheckEqual(3, v1.X); CheckEqual(6, v1.Y); } public void Scaling_Left() { Vector v1 = new Vector(1, 2); v1 = 3 * v1; CheckEqual(3, v1.X); CheckEqual(6, v1.Y); } public void Scaling_Right() { Vector v1 = new Vector(1, 2); v1 = v1 * 3; CheckEqual(3, v1.X); CheckEqual(6, v1.Y); } public void Addition() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(-7, -11); Vector expected = new Vector(-4, -7); CheckEqual(expected, v1 + v2); CheckEqual(expected, v2 + v1); } public void Addition_InPlace() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(-7, -11); Vector v3 = v1; Vector expected = new Vector(-4, -7); v1 += v2; v2 += v3; CheckEqual(expected, v1); CheckEqual(expected, v2); } public void Subtraction() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(-7, -11); Vector expected = new Vector(10, 15); CheckEqual(expected, v1 - v2); CheckEqual(-expected, v2 - v1); } public void Subtraction_InPlace() { Vector v1 = new Vector(3, 4); Vector v2 = new Vector(-7, -11); Vector v3 = v1; Vector expected = new Vector(10, 15); v1 -= v2; v2 -= v3; CheckEqual(expected, v1); CheckEqual(-expected, v2); } public void ScalarDivision_InPlace() { Vector v1 = new Vector(16, 32); Vector expected = new Vector(2, 4); v1 /= 8; CheckEqual(expected, v1); } public void ScalarDivision_Reverse() { Vector v1 = new Vector(16, 32); Vector expected = new Vector(8.0/16.0, 8.0/32.0); v1 = 8 / v1; CheckEqual(expected, v1); } public void ScalarDivision_Right() { Vector v1 = new Vector(16, 32); Vector expected = new Vector(2, 4); v1 = v1 / 8; CheckEqual(expected, v1); } public void Normalization() { Vector v1 = new Vector(3, 4); v1.Normalize(); CheckEqual(new Vector(3.0/5.0, 4.0/5.0), v1); } public void Normalization_ZeroLength() { Vector v1 = new Vector(0, 0); v1.Normalize(); Check(Vector.IsNaN(v1)); } public void NormalizedCopy() { Vector v1 = new Vector(3, 4); CheckEqual(new Vector(3.0/5.0, 4.0/5.0), v1.NormalizedCopy()); CheckEqual(new Vector(3, 4), v1); } public void NormalizedCopy_ZeroLength() { Vector v1 = new Vector(0, 0); Check(Vector.IsNaN(v1.NormalizedCopy())); } public void PerpCCW() { Vector v1 = Vector.UnitX; CheckEqual(Vector.UnitY, v1.PerpCCW()); } public void PerpCW() { Vector v1 = Vector.UnitY; CheckEqual(Vector.UnitX, v1.PerpCW()); } public void IsUnitLength_True() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 1); Check(v1.IsUnitLength()); } public void IsUnitLength_False() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 2); CheckFalse(v1.IsUnitLength()); } public void StaticRotate_Angle() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 2); Vector v2 = Vector.UnitX * 2; v2 = Vector.Rotate(v2, Math.PI / 4); CheckEqual(v1, v2); } public void StaticRotate_Vector() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 2); Vector v2 = Vector.UnitX; v2 = Vector.Rotate(v2, v1); CheckEqual(v1, v2); } public void Rotate_Angle() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 2); Vector v2 = Vector.UnitX * 2; v2.Rotate(Math.PI / 4); CheckEqual(v1, v2); } public void Rotate_Angle_0() { Vector v1 = Vector.UnitX; v1.Rotate(0); CheckEqual(Vector.UnitX, v1); } public void Rotate_Angle_2PI() { Vector v1 = new Vector(10, -10); v1.Rotate(2 * Math.PI); CheckEqual(new Vector(10, -10), v1); } public void Rotate_Angle_PI() { Vector v1 = new Vector(10, -10); v1.Rotate(Math.PI); CheckEqual(new Vector(-10, 10), v1); } public void Rotate_Vector() { Vector v1 = Vector.BuildFromAngleMagnitude(Math.PI / 4, 2); Vector v2 = Vector.UnitX; v2.Rotate(v1); CheckEqual(v1, v2); } public void Vector_IsNotNaN() { Vector v1 = new Vector(1, 2); CheckFalse(Vector.IsNaN(v1)); } public void Vector_IsNan_JustX() { Vector v1 = new Vector(Scalar.NaN, 2); Check(Vector.IsNaN(v1)); } public void Vector_IsNan_JustY() { Vector v1 = new Vector(1, Scalar.NaN); Check(Vector.IsNaN(v1)); } public void Vector_IsNan_XY() { Vector v1 = new Vector(Scalar.NaN, Scalar.NaN); Check(Vector.IsNaN(v1)); } public void Vector_ToString() { Vector v1 = new Vector(1, 2); CheckEqual("<1 : 2>", v1.ToString()); } public void Vector_ToString_Fuzzy() { Vector v1 = new Vector(1.0/3.0, 2.0/3.0); CheckEqual("<0.3333333333 : 0.6666666667>", v1.ToString()); } public void MinMax() { Vector v1 = new Vector(8, 1); Vector v2 = new Vector(3, 24); Vector v3, v4; v1.MinMax(v2, out v3, out v4); Check(v3.X == 3 && v3.Y == 1); Check(v4.X == 8 && v4.Y == 24); } public class CompareToTests : TestFixture { public void CompletelyUnequal() { var a = new Vector(7, 2); var b = new Vector(2, 1); Check(a.CompareTo(b) > 0); Check(b.CompareTo(a) < 0); } public void CompletelyEqual() { var a = new Vector(7, 2); var b = new Vector(7, 2); Check(a.CompareTo(b) == 0); Check(b.CompareTo(a) == 0); } public void XsEqual() { var a = new Vector(7, 2); var b = new Vector(7, 1); Check(a.CompareTo(b) > 0); Check(b.CompareTo(a) < 0); } public void YsEqual() { var a = new Vector(2, 7); var b = new Vector(1, 7); Check(a.CompareTo(b) > 0); Check(b.CompareTo(a) < 0); } } public class ToStringTests : TestFixture { public void Fractions() { var vector = new Vector(1.125, 5.321); CheckEqual("<1.125 : 5.321>", vector.ToString()); } public void Basic() { var vector = new Vector(1, 5); CheckEqual("<1 : 5>", vector.ToString()); } public void Infinity() { var vector = new Vector(Scalar.PositiveInfinity, Scalar.PositiveInfinity); CheckEqual("", vector.ToString()); } public void NegativeInfinity() { var vector = new Vector(Scalar.NegativeInfinity, Scalar.NegativeInfinity); CheckEqual("<-Infinity : -Infinity>", vector.ToString()); } public void NaN() { var vector = new Vector(Scalar.NaN, Scalar.NaN); CheckEqual("", vector.ToString()); } public class FormatProviders : UnitTestSharp.TestFixture { private static NumberFormatInfo formatter = System.Globalization.CultureInfo.GetCultureInfo("de-DE").NumberFormat; public void Basic() { var vector = new Vector(1, 5); CheckEqual("<1 : 5>", vector.ToString(formatter)); } public void Fractions() { var vector = new Vector(1.125, 5.321); CheckEqual("<1,125 : 5,321>", vector.ToString(formatter)); } public void Infinity() { var vector = new Vector(Scalar.PositiveInfinity, Scalar.PositiveInfinity); string symbol = formatter.PositiveInfinitySymbol; CheckEqual($"<{symbol} : {symbol}>", vector.ToString(formatter)); } public void NegativeInfinity() { var vector = new Vector(Scalar.NegativeInfinity, Scalar.NegativeInfinity); string symbol = formatter.NegativeInfinitySymbol; CheckEqual($"<{symbol} : {symbol}>", vector.ToString(formatter)); } public void NaN() { var vector = new Vector(Scalar.NaN, Scalar.NaN); string symbol = formatter.NaNSymbol; CheckEqual($"<{symbol} : {symbol}>", vector.ToString(formatter)); } } public class CustomFormatter : UnitTestSharp.TestFixture { public void Fractions() { var vector = new Vector(1.125, 5.321); CheckEqual("", vector.ToString("MOM 0.#")); } public void Basic() { var vector = new Vector(1, 5); CheckEqual("", vector.ToString("MOM 0.#")); } public void Infinity() { var vector = new Vector(Scalar.PositiveInfinity, Scalar.PositiveInfinity); CheckEqual("", vector.ToString("MOM 0.#")); } public void NegativeInfinity() { var vector = new Vector(Scalar.NegativeInfinity, Scalar.NegativeInfinity); CheckEqual("<-Infinity : -Infinity>", vector.ToString("MOM 0.#")); } public void NaN() { var vector = new Vector(Scalar.NaN, Scalar.NaN); CheckEqual("", vector.ToString("MOM 0.#")); } } } public class BitsToHexCodeTests : UnitTestSharp.TestFixture { public void Basic() { var vector = new Vector(1, 5); string bits1 = Scalar.BitsToHexCode(1); string bits5 = Scalar.BitsToHexCode(5); CheckEqual(String.Format("<{0} : {1}>", bits1, bits5), Vector.BitsToHexCode(vector)); } } public class Parse : TestFixture { public void Basic() { var text = "<10.45 : 11.234>"; var expected = new Vector(10.45, 11.234); var actual = Vector.Parse(text); CheckEqual(expected, actual); } public void NaN() { var text = ""; var actual = Vector.Parse(text); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); } public void Infinity() { var text = ""; var actual = Vector.Parse(text); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); } public class FormatProviders : UnitTestSharp.TestFixture { private static NumberFormatInfo formatter = System.Globalization.CultureInfo.GetCultureInfo("de-DE").NumberFormat; public void Basic() { var text = "<3000,23 : 7043,1>"; var expected = new Vector(3000.23, 7043.1); var actual = Vector.Parse(text, formatter); CheckEqual(expected, actual); } public void NaN() { string symbol = formatter.NaNSymbol; var text = $"<{symbol} : {symbol}>"; var actual = Vector.Parse(text, formatter); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); } public void Infinity() { string inf = formatter.PositiveInfinitySymbol; string neg = formatter.NegativeInfinitySymbol; var text = $"<{inf} : {neg}>"; var actual = Vector.Parse(text, formatter); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); } } public class CustomFormatter : UnitTestSharp.TestFixture { public void Basic() { var text = "<3,000.23 : 7,043.1>"; var expected = new Vector(3000.23, 7043.1); var actual = Vector.Parse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float); CheckEqual(expected, actual); } public void NaN() { var text = ""; var actual = Vector.Parse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); } public void Infinity() { var text = ""; var actual = Vector.Parse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); } } } public class TryParse : TestFixture { public void Basic() { var text = "<10.45 : 11.234>"; var expected = new Vector(10.45, 11.234); Vector actual; bool success = Vector.TryParse(text, out actual); CheckEqual(expected, actual); Check(success); } public void HexCodes() { var text = "<0x3FF0000000000000 : 0x4000000000000000>"; var expected = new Vector(1, 2); Vector actual; bool success = Vector.TryParse(text, out actual); CheckEqual(expected, actual); Check(success); } public void MixedNumberAndHexCode() { var text = "<0x3FF0000000000000 : 2.0>"; var expected = new Vector(1, 2); Vector actual; bool success = Vector.TryParse(text, out actual); CheckEqual(expected, actual); Check(success); } public void NaN() { var text = ""; Vector actual; bool success = Vector.TryParse(text, out actual); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); Check(success); } public void Infinity() { var text = ""; Vector actual; bool success = Vector.TryParse(text, out actual); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); Check(success); } public class FormatProviders : UnitTestSharp.TestFixture { private static NumberFormatInfo formatter = System.Globalization.CultureInfo.GetCultureInfo("de-DE").NumberFormat; public void Basic() { var text = "<3000,23 : 7043,1>"; var expected = new Vector(3000.23, 7043.1); Vector actual; bool success = Vector.TryParse(text, formatter, out actual); CheckEqual(expected, actual); Check(success); } public void NaN() { string symbol = formatter.NaNSymbol; var text = $"<{symbol} : {symbol}>"; Vector actual; bool success = Vector.TryParse(text, formatter, out actual); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); Check(success); } public void Infinity() { string inf = formatter.PositiveInfinitySymbol; string neg = formatter.NegativeInfinitySymbol; var text = $"<{inf} : {neg}>"; Vector actual; bool success = Vector.TryParse(text, formatter, out actual); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); Check(success); } } public class CustomFormatter : UnitTestSharp.TestFixture { public void Basic() { var text = "<3,000.23 : 7,043.1>"; var expected = new Vector(3000.23, 7043.1); Vector actual; bool success = Vector.TryParse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, out actual); CheckEqual(expected, actual); Check(success); } public void NaN() { var text = ""; Vector actual; bool success = Vector.TryParse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, out actual); Check(Scalar.IsNaN(actual.X)); Check(Scalar.IsNaN(actual.Y)); Check(success); } public void Infinity() { var text = ""; Vector actual; bool success = Vector.TryParse(text, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, out actual); Check(Scalar.IsInfinity(actual.X)); Check(Scalar.IsNegativeInfinity(actual.Y)); Check(success); } } } public class Bisection : TestFixture { public void Basic() { var vector1 = new Vector(10, 0); var vector2 = new Vector(0, 20); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(Math.Sqrt(2) / 2, Math.Sqrt(2) / 2), bisector); } public void Antiparallel() { var vector1 = new Vector(10, 0); var vector2 = new Vector(-10, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(0, 1), bisector); } public void Antiparallel_DifferentLength() { var vector1 = new Vector(10, 0); var vector2 = new Vector(-20, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(0, 1), bisector); } public void Parallel() { var vector1 = new Vector(10, 0); var vector2 = new Vector(10, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(1, 0), bisector); } public void OneZero_First() { var vector1 = new Vector(10, 0); var vector2 = new Vector(0, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(0, 0), bisector); } public void OneZero_Second() { var vector1 = new Vector(10, 0); var vector2 = new Vector(0, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(0, 0), bisector); } public void TwoZero() { var vector1 = new Vector(0, 0); var vector2 = new Vector(0, 0); var bisector = Vector.GetBisector(vector1, vector2); CheckEqual(new Vector(0, 0), bisector); } } public class CalculatePseudoangle : TestFixture { public void _0() { CheckEqual(0, new Vector(4, 0).CalculatePseudoangle()); } public void _1() { CheckEqual(.125, new Vector(2, 2).CalculatePseudoangle()); } public void _2() { CheckEqual(.25, new Vector(0, 2).CalculatePseudoangle()); } public void _3() { CheckEqual(.375, new Vector(-2, 2).CalculatePseudoangle()); } public void _4() { CheckEqual(.5, new Vector(-16, 0).CalculatePseudoangle()); } public void _5() { CheckEqual(.625, new Vector(-16, -16).CalculatePseudoangle()); } public void _6() { CheckEqual(.75, new Vector(0, -7).CalculatePseudoangle()); } public void _7() { CheckEqual(7.0/8.0, new Vector(7, -7).CalculatePseudoangle()); } } public class IsAngleGreater : TestFixture { public void Quad_1() { var vec1 = new Vector(1, 1); var vec2 = new Vector(1, 2); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void Quad_2() { var vec1 = new Vector(1, 1); var vec2 = new Vector(-1, 2); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void Quad_3() { var vec1 = new Vector(1, 1); var vec2 = new Vector(-1, -2); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void Quad_4() { var vec1 = new Vector(1, 1); var vec2 = new Vector(1, -2); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void ZeroVec1() { var vec1 = new Vector(0, 0); var vec2 = new Vector(1, 2); CheckThrow(typeof(System.Exception)); Vector.IsAngleGreater(vec1, vec2); } public void ZeroVec2() { var vec1 = new Vector(1, 1); var vec2 = new Vector(0, 0); CheckThrow(typeof(System.Exception)); Vector.IsAngleGreater(vec1, vec2); } public void ZeroReference() { var vec1 = new Vector(1, 1); var vec2 = new Vector(1, 2); CheckThrow(typeof(System.Exception)); Vector.IsAngleGreater(vec1, vec2, Vector.Zero); } public void Parallel() { var vec1 = new Vector(1, 1); var vec2 = new Vector(2, 2); CheckEqual(0, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(0, Vector.IsAngleGreater(vec2, vec1)); } public void AntiParallel() { var vec1 = new Vector(1, 1); var vec2 = new Vector(-2, -2); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void Perp_Left() { var vec1 = new Vector(1, 1); var vec2 = new Vector(-1, 1); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void Perp_Right() { var vec1 = new Vector(1, 1); var vec2 = new Vector(1,-1); CheckEqual(-1, Vector.IsAngleGreater(vec1, vec2)); CheckEqual(1, Vector.IsAngleGreater(vec2, vec1)); } public void SortsSmallList() { var points = new List(new Vector[] { new Vector(0.0000081806, -0.0000692028), new Vector(0.0000244579, 0.0000501783), new Vector(0.000055804, -0.0000014029), new Vector(-0.0000539388, -0.0000143758), new Vector(-0.0000354836, 0.0000430925) }); var expected = new Vector[] { points[1], points[4], points[3], points[0], points[2], }; points.Sort((x, y) => Vector.IsAngleGreater(x, y)); CheckEqual(expected, points); } } public class IsAngleGreater_WithReference : TestFixture { public void Basic_1() { Vector lhs = new Vector(1, 1); Vector rhs = new Vector(0, 1); Vector reference = new Vector(-1, 1); CheckEqual(-1, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(1, Vector.IsAngleGreater(rhs, lhs, reference)); } public void ZeroReference() { Vector lhs = new Vector(1, 1); Vector rhs = new Vector(0, 1); Vector reference = new Vector(0, 0); CheckThrow(typeof(Exception)); Vector.IsAngleGreater(lhs, rhs, reference); } public void ZeroLhs() { Vector lhs = new Vector(0, 0); Vector rhs = new Vector(0, 1); Vector reference = new Vector(-1, 1); CheckThrow(typeof(Exception)); Vector.IsAngleGreater(lhs, rhs, reference); } public void ZeroRhs() { Vector lhs = new Vector(1, 1); Vector rhs = new Vector(0, 0); Vector reference = new Vector(-1, 1); CheckThrow(typeof(Exception)); Vector.IsAngleGreater(lhs, rhs, reference); } public void LhsEqualsReference() { Vector lhs = new Vector(-1, 1); Vector rhs = new Vector(0, 1); Vector reference = new Vector(-1, 1); CheckEqual(-1, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(1, Vector.IsAngleGreater(rhs, lhs, reference)); } public void RhsEqualsReference() { Vector lhs = new Vector(0, 1); Vector rhs = new Vector(-2, 2); Vector reference = new Vector(-1, 1); CheckEqual(1, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(-1, Vector.IsAngleGreater(rhs, lhs, reference)); } public void LhsEqualsRhs() { Vector lhs = new Vector(-1, 1); Vector rhs = new Vector(-2, 2); Vector reference = new Vector(2, 1); CheckEqual(0, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(0, Vector.IsAngleGreater(rhs, lhs, reference)); } public void AllEqual() { Vector lhs = new Vector(2, 1); Vector rhs = new Vector(2, 1); Vector reference = new Vector(2, 1); CheckEqual(0, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(0, Vector.IsAngleGreater(rhs, lhs, reference)); } public void RhsEqualsReference2() { // rhs differs from reference by one bit in mantissa. var lhs = Vector.Parse("<0x3FD3C6EF372FE952 : 0x3FEE6F0E13445500>"); var rhs = Vector.Parse("<0x3FE9E3779B97F4A7 : 0xBFE2CF2304755A5F>"); var reference = Vector.Parse("<0x3FE9E3779B97F4A7 : 0xBFE2CF2304755A5E>"); CheckEqual(1, Vector.IsAngleGreater(lhs, rhs, reference)); CheckEqual(-1, Vector.IsAngleGreater(rhs, lhs, reference)); } } public class LerpTests : TestFixture { public void T_0() { CheckEqual(new Vector(2, 3), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 0)); } public void T_Quarter() { CheckEqual(new Vector(1.5, 2.5), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 0.25)); } public void T_Half() { CheckEqual(new Vector(1, 2), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 0.5)); } public void T_ThreeQuarter() { CheckEqual(new Vector(0.5, 1.5), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 0.75)); } public void T_1() { CheckEqual(new Vector(0, 1), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 1)); } public void T_OverUnity() { CheckEqual(new Vector(-2, -1), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: 2)); } public void T_Negative() { CheckEqual(new Vector(4, 5), Vector.Lerp(new Vector(2, 3), new Vector(0, 1), t: -1)); } } } }