using System; using System.Collections.Generic; using System.Linq; using UnitTestSharp; namespace Blacklight.Bezier.UnitTests { public class PieceShellSetsTests : TestFixture { public static ShellTestSet SetOf(ShellSample[] samples, double[] thickness) { return new ShellTestSet("Name", samples, thickness.Select(value => value * value).ToArray(), samples.Select(ReferenceDistance.Solve).ToArray()); } public class FatLineGapTests : TestFixture { public void PointAboveTheVertex_IsItsOffsetFromTheChord() { double gap = PieceShellSets.FatLineGap(ShellSample.FromPosition(0, 5, 2)); CheckLess(Math.Abs(5 / Math.Sqrt(2) - gap), 1e-12); } public void PointOnTheChord_IsZero() { CheckEqual(0.0, PieceShellSets.FatLineGap(ShellSample.FromPosition(1, 1, 2))); } public void PointInsideTheFatLine_IsNegative() { CheckLess(PieceShellSets.FatLineGap(ShellSample.FromPosition(1, 0.75, 2)), 0.0); } public void NeverExceedsTheDistance() { IEnumerable samples = SampleSets.Create(samplesPerSet: 300, seed: 3) .SelectMany(set => set.Samples) .Concat(PieceShellSets.Rendered(side: 48, seed: 3).Samples); foreach (ShellSample sample in samples) { double distance = ReferenceDistance.Solve(sample).Distance; CheckTrue(PieceShellSets.FatLineGap(sample) <= distance * (1 + 1e-9) + 1e-12); } } } public class FromSampleSetsTests : TestFixture { public void ThicknessStaysWithinATenthOfTheDistance() { List sets = SampleSets.Create(samplesPerSet: 300, seed: 3); List references = sets .Select(set => set.Samples.Select(ReferenceDistance.Solve).ToArray()).ToList(); foreach (ShellTestSet set in PieceShellSets.FromSampleSets(sets, references, ShellTestSets.NearEdge, seed: 3)) { for (int i = 0; i < set.Samples.Length; i++) { double ratio = Math.Sqrt(set.G[i]) / set.References[i].Distance; CheckTrue(ratio >= 0.9 * (1 - 1e-9) && ratio <= 1.1 * (1 + 1e-9)); } } } public void PixelOnTheCurve_IsDropped() { var set = new SampleSet("Name", new[] { ShellSample.FromPosition(1, 0.5, 2), ShellSample.FromPosition(0, 3, 2), }); var references = new List { new[] { new ReferenceResult(0, 1), new ReferenceResult(3, 0) }, }; List pieceSets = PieceShellSets.FromSampleSets(new List { set }, references, random => 0, seed: 3); CheckEqual(1, pieceSets[0].Samples.Length); CheckEqual(3.0, pieceSets[0].Samples[0].Y); CheckEqual(9.0, pieceSets[0].G[0]); } } public class RenderedTests : TestFixture { public void ThicknessIsATenthOfTheChordAtMost() { ShellTestSet set = PieceShellSets.Rendered(side: 48, seed: 3); CheckEqual(48 * 48, set.Samples.Length); for (int i = 0; i < set.Samples.Length; i++) { double end = set.Samples[i].End; double chord = end * Math.Sqrt(1 + 0.25 * end * end); double thickness = Math.Sqrt(set.G[i]); CheckTrue(thickness > 0 && thickness <= 0.1 * chord * (1 + 1e-12)); } } public void References_AreEachSamplesSolution() { ShellTestSet set = PieceShellSets.Rendered(side: 16, seed: 3); for (int i = 0; i < set.Samples.Length; i++) { CheckEqual(ReferenceDistance.Solve(set.Samples[i]).Distance, set.References[i].Distance); } } } public class RenderedLayoutTests : TestFixture { public void PixelsInOneTile_ShareAPiece() { ShellTestSet set = PieceShellSets.Rendered(side: 64, seed: 3); int last = PieceShellSets.TileSide - 1; CheckEqual(set.Samples[0].End, set.Samples[last * 64 + last].End); CheckEqual(set.G[0], set.G[last * 64 + last]); } public void NeighbouringTiles_HaveTheirOwnPiece() { ShellTestSet set = PieceShellSets.Rendered(side: 64, seed: 3); CheckNotEqual(set.Samples[0].End, set.Samples[PieceShellSets.TileSide].End); CheckNotEqual(set.Samples[0].End, set.Samples[PieceShellSets.TileSide * 64].End); } } public class FatLineSkipsTests : TestFixture { public void CountsPixelsWhoseGapReachesTheirThickness() { ShellSample farAbove = ShellSample.FromPosition(0, 5, 2); ShellTestSet set = SetOf(new[] { farAbove, farAbove, farAbove }, new[] { 1.0, 5 / Math.Sqrt(2), 4.0 }); CheckEqual(2, PieceShellSets.FatLineSkips(set)); } } public class DisagreementsTests : TestFixture { public void CountsAnswersOnOppositeSidesOfAHalf() { var first = new[] { 0f, 1f, 1f, 0f, 1f }; var second = new[] { 0f, 0f, 1f, 1f, 1f }; CheckEqual(2, PieceShellSets.Disagreements(first, second, count: 5)); } public void IgnoresEntriesPastCount() { CheckEqual(0, PieceShellSets.Disagreements(new[] { 0f, 1f }, new[] { 0f, 0f }, count: 1)); } } } }