using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Annulus.BezierCurves; using Azimuth; namespace Annulus.UnitTests.BezierCurve { public class QuadraticBezierCurveTests : UnitTestSharp.TestFixture { public class EvaluateTests : UnitTestSharp.TestFixture { QuadraticBezierCurve curve = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(1, 1), endPoint = new Vector(2, 0), }; public void T_0() { CheckEqual(new Vector(0, 0), curve.Evaluate(0)); } public void T_1() { CheckEqual(new Vector(2, 0), curve.Evaluate(1)); } public void T_Quarter() { CheckEqual(new Vector(0.5, 0.375), curve.Evaluate(0.25)); } public void T_Half() { CheckEqual(new Vector(1, 0.5), curve.Evaluate(0.5)); } public void T_ThreeQuarter() { CheckEqual(new Vector(1.5, 0.375), curve.Evaluate(0.75)); } public void Negative() { CheckEqual(new Vector(-2, -4), curve.Evaluate(-1)); } public void OverUnity() { CheckEqual(new Vector(4, -4), curve.Evaluate(2)); } } public class SplitTests : UnitTestSharp.TestFixture { QuadraticBezierCurve curve = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(1, 1), endPoint = new Vector(2, 0), }; public void T_0() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 0, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve(); CheckEqual(expectedLhs, lhs); CheckEqual(curve, rhs); } public void T_1() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 1, lhs: out lhs, rhs: out rhs); var expectedRhs = new QuadraticBezierCurve { startPoint = curve.endPoint, controlPoint = curve.endPoint, endPoint = curve.endPoint, }; CheckEqual(expectedRhs, rhs); CheckEqual(curve, lhs); } public void T_Quarter() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 0.25, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(0.25, 0.25), endPoint = new Vector(0.5, 0.375), }; var expectedRhs = new QuadraticBezierCurve { startPoint = new Vector(0.5, 0.375), controlPoint = new Vector(1.25, 0.75), endPoint = new Vector(2, 0), }; CheckEqual(expectedLhs, lhs); CheckEqual(expectedRhs, rhs); } public void T_Half() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 0.5, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(0.5, 0.5), endPoint = new Vector(1, 0.5), }; var expectedRhs = new QuadraticBezierCurve { startPoint = new Vector(1, 0.5), controlPoint = new Vector(1.5, 0.5), endPoint = new Vector(2, 0), }; CheckEqual(expectedLhs, lhs); CheckEqual(expectedRhs, rhs); } public void T_ThreeQuarter() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 0.75, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(0.75, 0.75), endPoint = new Vector(1.5, 0.375), }; var expectedRhs = new QuadraticBezierCurve { startPoint = new Vector(1.5, 0.375), controlPoint = new Vector(1.75, 0.25), endPoint = new Vector(2, 0), }; CheckEqual(expectedLhs, lhs); CheckEqual(expectedRhs, rhs); } public void T_Negative() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: -1, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(-1, -1), endPoint = new Vector(-2, -4), }; var expectedRhs = new QuadraticBezierCurve { startPoint = new Vector(-2, -4), controlPoint = new Vector(0, 2), endPoint = new Vector(2, 0), }; CheckEqual(expectedLhs, lhs); CheckEqual(expectedRhs, rhs); } public void T_OverUnity() { QuadraticBezierCurve lhs, rhs; QuadraticBezierCurve.Split(curve, t: 2, lhs: out lhs, rhs: out rhs); var expectedLhs = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(2, 2), endPoint = new Vector(4, -4), }; var expectedRhs = new QuadraticBezierCurve { startPoint = new Vector(4, -4), controlPoint = new Vector(3, -1), endPoint = new Vector(2, 0), }; CheckEqual(expectedLhs, lhs); CheckEqual(expectedRhs, rhs); } } public class ToStringTests : UnitTestSharp.TestFixture { QuadraticBezierCurve curve = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(1, 1), endPoint = new Vector(2, 0), }; public void Basic() { CheckEqual("<0 : 0> : <1 : 1> : <2 : 0>", curve.ToString()); } } public class InverseTests : UnitTestSharp.TestFixture { QuadraticBezierCurve curve = new QuadraticBezierCurve { startPoint = new Vector(0, 0), controlPoint = new Vector(1, 1), endPoint = new Vector(2, 0), }; public void OnStartPoint() { var point = new Vector(0, 0); CheckEqual(0, curve.Inverse(point)); } public void OnEndPoint() { var point = new Vector(2, 0); CheckEqual(1, curve.Inverse(point)); } public void OnMidPoint() { CheckEqual(0.5, curve.Inverse(curve.Evaluate(0.5))); } public void OnCurve() { var point = new Vector(2.0/3.0, 4.0/9.0); CheckEqual(1.0/3.0, curve.Inverse(point)); } public void OnCurveAtIrrationalPoint() { CheckEqual(1.0/Math.PI, curve.Inverse(curve.Evaluate(1.0 / Math.PI))); } public void OffCurveAboveMidpoint() { var point = curve.Evaluate(0.5); point.Y += 10; // The exact value isn't really important. CheckEqual(-9.5, curve.Inverse(point)); } public void OffCurveNegative() { var point = curve.startPoint; point.X -= 10; // The exact value isn't really important. CheckEqual(1, curve.Inverse(point)); } } } }