From d6cda905c40385831361115b3a7e737072df0eaf Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sat, 11 Jan 2020 21:14:48 +0100 Subject: [PATCH] Implemented cubic noise --- CubicNoise/Noisers/CubicNoiseEngine.cs | 75 ++++++++++++++++- CubicNoiseTests/CubicNoiseTests.cs | 108 +++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 CubicNoiseTests/CubicNoiseTests.cs diff --git a/CubicNoise/Noisers/CubicNoiseEngine.cs b/CubicNoise/Noisers/CubicNoiseEngine.cs index 4ad1199..5365ea0 100644 --- a/CubicNoise/Noisers/CubicNoiseEngine.cs +++ b/CubicNoise/Noisers/CubicNoiseEngine.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text; using CubicNoise.Contracts; @@ -7,23 +8,89 @@ namespace CubicNoise.Noisers { public sealed class CubicNoiseEngine : INoiseEngine { - private Dictionary intParameters; + private const int RANDOM_NUMBER_A = 134_775_813; + private const int RANDOM_NUMBER_B = 1_103_515_245; + + private readonly int octave; + private readonly int periodX; + private readonly int periodY; private int seed; public CubicNoiseEngine(int seed, Dictionary intParameters) { - this.intParameters = intParameters; this.seed = seed; + this.octave = intParameters?.ContainsKey(CubicNoiseIntParameters.OCTAVE) == true ? intParameters[CubicNoiseIntParameters.OCTAVE] : 16; + this.periodX = intParameters?.ContainsKey(CubicNoiseIntParameters.PERIOD_X) == true ? intParameters[CubicNoiseIntParameters.PERIOD_X] : 1_000; + this.periodY = intParameters?.ContainsKey(CubicNoiseIntParameters.PERIOD_Y) == true ? intParameters[CubicNoiseIntParameters.PERIOD_Y] : 512; } public float Get(float x) { - throw new NotImplementedException(); + var xi = (int)Math.Floor(x / this.octave); + var octaveXFactor = x / this.octave - xi; + + return this.Interpolation( + a: this.RandomNumberGenerator(x: this.DeterminePatch(xi - 1, this.periodX), y: 0), + b: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 0, this.periodX), y: 0), + c: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 1, this.periodX), y: 0), + d: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 2, this.periodX), y: 0), + x: octaveXFactor) * 0.5f + 0.25f; } public float Get(float x, float y) { - throw new NotImplementedException(); + var xi = (int)Math.Floor(x / octave); + var yi = (int)Math.Floor(y / octave); + + var octaveXFactor = x / octave - xi; + var octaveYFactor = y / octave - yi; + + return this.Interpolation( + a: this.Interpolation( + a: this.RandomNumberGenerator(x: this.DeterminePatch(xi - 1, this.periodX), y: this.DeterminePatch(yi - 1 + 0, this.periodY)), + b: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 0, this.periodX), y: this.DeterminePatch(yi - 1 + 0, this.periodY)), + c: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 1, this.periodX), y: this.DeterminePatch(yi - 1 + 0, this.periodY)), + d: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 2, this.periodX), y: this.DeterminePatch(yi - 1 + 0, this.periodY)), + x: octaveXFactor), + + b: this.Interpolation( + a: this.RandomNumberGenerator(x: this.DeterminePatch(xi - 1, this.periodX), y: this.DeterminePatch(yi - 1 + 1, this.periodY)), + b: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 0, this.periodX), y: this.DeterminePatch(yi - 1 + 1, this.periodY)), + c: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 1, this.periodX), y: this.DeterminePatch(yi - 1 + 1, this.periodY)), + d: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 2, this.periodX), y: this.DeterminePatch(yi - 1 + 1, this.periodY)), + x: octaveXFactor), + + c: this.Interpolation( + a: this.RandomNumberGenerator(x: this.DeterminePatch(xi - 1, this.periodX), y: this.DeterminePatch(yi - 1 + 2, this.periodY)), + b: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 0, this.periodX), y: this.DeterminePatch(yi - 1 + 2, this.periodY)), + c: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 1, this.periodX), y: this.DeterminePatch(yi - 1 + 2, this.periodY)), + d: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 2, this.periodX), y: this.DeterminePatch(yi - 1 + 2, this.periodY)), + x: octaveXFactor), + + d: this.Interpolation( + a: this.RandomNumberGenerator(x: this.DeterminePatch(xi - 1, this.periodX), y: this.DeterminePatch(yi - 1 + 3, this.periodY)), + b: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 0, this.periodX), y: this.DeterminePatch(yi - 1 + 3, this.periodY)), + c: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 1, this.periodX), y: this.DeterminePatch(yi - 1 + 3, this.periodY)), + d: this.RandomNumberGenerator(x: this.DeterminePatch(xi + 2, this.periodX), y: this.DeterminePatch(yi - 1 + 3, this.periodY)), + x: octaveXFactor), + + x: octaveYFactor) * 0.5f + 0.25f; + } + + private float RandomNumberGenerator(int x, int y) + { + return (float)((((x ^ y) * RANDOM_NUMBER_A) ^ (this.seed + x)) * (((RANDOM_NUMBER_B * x) << 16) ^ (RANDOM_NUMBER_B * y) - RANDOM_NUMBER_A)) / int.MaxValue; + } + + private int DeterminePatch(int coordinate, int period) + { + return coordinate % period; + } + + private float Interpolation(float a, float b, float c, float d, float x) + { + var p = (d - c) - (a - b); + return x * (x * (x * p + ((a - b) - p)) + (c - a)) + b; } } } diff --git a/CubicNoiseTests/CubicNoiseTests.cs b/CubicNoiseTests/CubicNoiseTests.cs new file mode 100644 index 0000000..96efd42 --- /dev/null +++ b/CubicNoiseTests/CubicNoiseTests.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CubicNoise; +using CubicNoise.Contracts; +using CubicNoise.Noisers; +using NUnit.Framework; + +namespace CubicNoiseTests +{ + public class CubicNoiseTests + { + [Test] + public void TestValidity() + { + var engineO57PX12PY16 = NoiseEngine.Create(new EngineParameters + { + Seed = "test seed".GetHashCode(), + Type = NoiseTypes.CUBIC_NOISE, + IntParameters = new Dictionary + { + { CubicNoiseIntParameters.OCTAVE, 57 }, + { CubicNoiseIntParameters.PERIOD_X, 12 }, + { CubicNoiseIntParameters.PERIOD_Y, 16 }, + }, + }); + + var engineO45PX16PY99 = NoiseEngine.Create(new EngineParameters + { + Seed = "test seed".GetHashCode(), + Type = NoiseTypes.CUBIC_NOISE, + IntParameters = new Dictionary + { + { CubicNoiseIntParameters.OCTAVE, 45 }, + { CubicNoiseIntParameters.PERIOD_X, 16 }, + { CubicNoiseIntParameters.PERIOD_Y, 99 }, + }, + }); + + Assert.That(engineO57PX12PY16, Is.Not.Null); + Assert.That(engineO45PX16PY99, Is.Not.Null); + + // Generated by means of https://github.com/jobtalle/CubicNoise/blob/master/c%23/CubicNoise.cs + var expectedValuesO57 = new List<(int X, int Y, float Result)> + { + (X: 0, Y: 0, Result: 0.1161f), (X: 0, Y: 1, Result: 0.1215f), (X: 0, Y: 2, Result: 0.1268f), (X: 0, Y: 3, Result: 0.1320f), (X: 0, Y: 4, Result: 0.1371f), (X: 0, Y: 5, Result: 0.1421f), (X: 0, Y: 6, Result: 0.1469f), (X: 0, Y: 7, Result: 0.1517f), (X: 0, Y: 8, Result: 0.1564f), (X: 0, Y: 9, Result: 0.1611f), + (X: 1, Y: 0, Result: 0.1213f), (X: 1, Y: 1, Result: 0.1265f), (X: 1, Y: 2, Result: 0.1315f), (X: 1, Y: 3, Result: 0.1363f), (X: 1, Y: 4, Result: 0.1411f), (X: 1, Y: 5, Result: 0.1458f), (X: 1, Y: 6, Result: 0.1503f), (X: 1, Y: 7, Result: 0.1548f), (X: 1, Y: 8, Result: 0.1592f), (X: 1, Y: 9, Result: 0.1635f), + (X: 2, Y: 0, Result: 0.1275f), (X: 2, Y: 1, Result: 0.1323f), (X: 2, Y: 2, Result: 0.1370f), (X: 2, Y: 3, Result: 0.1416f), (X: 2, Y: 4, Result: 0.1460f), (X: 2, Y: 5, Result: 0.1504f), (X: 2, Y: 6, Result: 0.1546f), (X: 2, Y: 7, Result: 0.1588f), (X: 2, Y: 8, Result: 0.1628f), (X: 2, Y: 9, Result: 0.1668f), + (X: 3, Y: 0, Result: 0.1345f), (X: 3, Y: 1, Result: 0.1390f), (X: 3, Y: 2, Result: 0.1435f), (X: 3, Y: 3, Result: 0.1477f), (X: 3, Y: 4, Result: 0.1519f), (X: 3, Y: 5, Result: 0.1559f), (X: 3, Y: 6, Result: 0.1598f), (X: 3, Y: 7, Result: 0.1637f), (X: 3, Y: 8, Result: 0.1674f), (X: 3, Y: 9, Result: 0.1710f), + (X: 4, Y: 0, Result: 0.1423f), (X: 4, Y: 1, Result: 0.1466f), (X: 4, Y: 2, Result: 0.1507f), (X: 4, Y: 3, Result: 0.1547f), (X: 4, Y: 4, Result: 0.1586f), (X: 4, Y: 5, Result: 0.1623f), (X: 4, Y: 6, Result: 0.1659f), (X: 4, Y: 7, Result: 0.1694f), (X: 4, Y: 8, Result: 0.1728f), (X: 4, Y: 9, Result: 0.1761f), + (X: 5, Y: 0, Result: 0.1510f), (X: 5, Y: 1, Result: 0.1550f), (X: 5, Y: 2, Result: 0.1588f), (X: 5, Y: 3, Result: 0.1625f), (X: 5, Y: 4, Result: 0.1661f), (X: 5, Y: 5, Result: 0.1695f), (X: 5, Y: 6, Result: 0.1728f), (X: 5, Y: 7, Result: 0.1760f), (X: 5, Y: 8, Result: 0.1790f), (X: 5, Y: 9, Result: 0.1820f), + (X: 6, Y: 0, Result: 0.1604f), (X: 6, Y: 1, Result: 0.1641f), (X: 6, Y: 2, Result: 0.1677f), (X: 6, Y: 3, Result: 0.1711f), (X: 6, Y: 4, Result: 0.1743f), (X: 6, Y: 5, Result: 0.1774f), (X: 6, Y: 6, Result: 0.1804f), (X: 6, Y: 7, Result: 0.1833f), (X: 6, Y: 8, Result: 0.1860f), (X: 6, Y: 9, Result: 0.1887f), + (X: 7, Y: 0, Result: 0.1705f), (X: 7, Y: 1, Result: 0.1740f), (X: 7, Y: 2, Result: 0.1773f), (X: 7, Y: 3, Result: 0.1804f), (X: 7, Y: 4, Result: 0.1833f), (X: 7, Y: 5, Result: 0.1861f), (X: 7, Y: 6, Result: 0.1888f), (X: 7, Y: 7, Result: 0.1913f), (X: 7, Y: 8, Result: 0.1938f), (X: 7, Y: 9, Result: 0.1961f), + (X: 8, Y: 0, Result: 0.1813f), (X: 8, Y: 1, Result: 0.1845f), (X: 8, Y: 2, Result: 0.1875f), (X: 8, Y: 3, Result: 0.1904f), (X: 8, Y: 4, Result: 0.1930f), (X: 8, Y: 5, Result: 0.1955f), (X: 8, Y: 6, Result: 0.1979f), (X: 8, Y: 7, Result: 0.2001f), (X: 8, Y: 8, Result: 0.2022f), (X: 8, Y: 9, Result: 0.2042f), + (X: 9, Y: 0, Result: 0.1927f), (X: 9, Y: 1, Result: 0.1957f), (X: 9, Y: 2, Result: 0.1985f), (X: 9, Y: 3, Result: 0.2010f), (X: 9, Y: 4, Result: 0.2034f), (X: 9, Y: 5, Result: 0.2056f), (X: 9, Y: 6, Result: 0.2076f), (X: 9, Y: 7, Result: 0.2095f), (X: 9, Y: 8, Result: 0.2113f), (X: 9, Y: 9, Result: 0.2129f), + + (X: 1123456, Y: -1123456, Result: 0.3548f), (X: 1123456, Y: -1123455, Result: 0.3397f), (X: 1123456, Y: -1123454, Result: 0.3245f), (X: 1123456, Y: -1123453, Result: 0.3090f), (X: 1123456, Y: -1123452, Result: 0.2934f), (X: 1123456, Y: -1123451, Result: 0.2776f), (X: 1123456, Y: -1123450, Result: 0.2617f), (X: 1123456, Y: -1123449, Result: 0.2457f), (X: 1123456, Y: -1123448, Result: 0.2297f), (X: 1123456, Y: -1123447, Result: 0.2135f), + (X: 1123457, Y: -1123456, Result: 0.3639f), (X: 1123457, Y: -1123455, Result: 0.3488f), (X: 1123457, Y: -1123454, Result: 0.3334f), (X: 1123457, Y: -1123453, Result: 0.3177f), (X: 1123457, Y: -1123452, Result: 0.3019f), (X: 1123457, Y: -1123451, Result: 0.2860f), (X: 1123457, Y: -1123450, Result: 0.2699f), (X: 1123457, Y: -1123449, Result: 0.2537f), (X: 1123457, Y: -1123448, Result: 0.2374f), (X: 1123457, Y: -1123447, Result: 0.2211f), + (X: 1123458, Y: -1123456, Result: 0.3728f), (X: 1123458, Y: -1123455, Result: 0.3574f), (X: 1123458, Y: -1123454, Result: 0.3419f), (X: 1123458, Y: -1123453, Result: 0.3261f), (X: 1123458, Y: -1123452, Result: 0.3101f), (X: 1123458, Y: -1123451, Result: 0.2940f), (X: 1123458, Y: -1123450, Result: 0.2777f), (X: 1123458, Y: -1123449, Result: 0.2613f), (X: 1123458, Y: -1123448, Result: 0.2448f), (X: 1123458, Y: -1123447, Result: 0.2283f), + (X: 1123459, Y: -1123456, Result: 0.3812f), (X: 1123459, Y: -1123455, Result: 0.3657f), (X: 1123459, Y: -1123454, Result: 0.3500f), (X: 1123459, Y: -1123453, Result: 0.3341f), (X: 1123459, Y: -1123452, Result: 0.3179f), (X: 1123459, Y: -1123451, Result: 0.3016f), (X: 1123459, Y: -1123450, Result: 0.2852f), (X: 1123459, Y: -1123449, Result: 0.2686f), (X: 1123459, Y: -1123448, Result: 0.2519f), (X: 1123459, Y: -1123447, Result: 0.2352f), + (X: 1123460, Y: -1123456, Result: 0.3891f), (X: 1123460, Y: -1123455, Result: 0.3735f), (X: 1123460, Y: -1123454, Result: 0.3577f), (X: 1123460, Y: -1123453, Result: 0.3416f), (X: 1123460, Y: -1123452, Result: 0.3253f), (X: 1123460, Y: -1123451, Result: 0.3089f), (X: 1123460, Y: -1123450, Result: 0.2923f), (X: 1123460, Y: -1123449, Result: 0.2755f), (X: 1123460, Y: -1123448, Result: 0.2587f), (X: 1123460, Y: -1123447, Result: 0.2418f), + (X: 1123461, Y: -1123456, Result: 0.3966f), (X: 1123461, Y: -1123455, Result: 0.3809f), (X: 1123461, Y: -1123454, Result: 0.3650f), (X: 1123461, Y: -1123453, Result: 0.3487f), (X: 1123461, Y: -1123452, Result: 0.3323f), (X: 1123461, Y: -1123451, Result: 0.3157f), (X: 1123461, Y: -1123450, Result: 0.2989f), (X: 1123461, Y: -1123449, Result: 0.2820f), (X: 1123461, Y: -1123448, Result: 0.2650f), (X: 1123461, Y: -1123447, Result: 0.2480f), + (X: 1123462, Y: -1123456, Result: 0.4036f), (X: 1123462, Y: -1123455, Result: 0.3878f), (X: 1123462, Y: -1123454, Result: 0.3717f), (X: 1123462, Y: -1123453, Result: 0.3554f), (X: 1123462, Y: -1123452, Result: 0.3388f), (X: 1123462, Y: -1123451, Result: 0.3221f), (X: 1123462, Y: -1123450, Result: 0.3052f), (X: 1123462, Y: -1123449, Result: 0.2881f), (X: 1123462, Y: -1123448, Result: 0.2710f), (X: 1123462, Y: -1123447, Result: 0.2537f), + (X: 1123463, Y: -1123456, Result: 0.4101f), (X: 1123463, Y: -1123455, Result: 0.3942f), (X: 1123463, Y: -1123454, Result: 0.3780f), (X: 1123463, Y: -1123453, Result: 0.3615f), (X: 1123463, Y: -1123452, Result: 0.3448f), (X: 1123463, Y: -1123451, Result: 0.3280f), (X: 1123463, Y: -1123450, Result: 0.3109f), (X: 1123463, Y: -1123449, Result: 0.2937f), (X: 1123463, Y: -1123448, Result: 0.2764f), (X: 1123463, Y: -1123447, Result: 0.2590f), + (X: 1123464, Y: -1123456, Result: 0.4160f), (X: 1123464, Y: -1123455, Result: 0.4000f), (X: 1123464, Y: -1123454, Result: 0.3837f), (X: 1123464, Y: -1123453, Result: 0.3671f), (X: 1123464, Y: -1123452, Result: 0.3503f), (X: 1123464, Y: -1123451, Result: 0.3333f), (X: 1123464, Y: -1123450, Result: 0.3162f), (X: 1123464, Y: -1123449, Result: 0.2988f), (X: 1123464, Y: -1123448, Result: 0.2814f), (X: 1123464, Y: -1123447, Result: 0.2639f), + (X: 1123465, Y: -1123456, Result: 0.4213f), (X: 1123465, Y: -1123455, Result: 0.4052f), (X: 1123465, Y: -1123454, Result: 0.3888f), (X: 1123465, Y: -1123453, Result: 0.3722f), (X: 1123465, Y: -1123452, Result: 0.3553f), (X: 1123465, Y: -1123451, Result: 0.3382f), (X: 1123465, Y: -1123450, Result: 0.3209f), (X: 1123465, Y: -1123449, Result: 0.3034f), (X: 1123465, Y: -1123448, Result: 0.2859f), (X: 1123465, Y: -1123447, Result: 0.2682f), + }; + + // Generated by means of https://github.com/jobtalle/CubicNoise/blob/master/c%23/CubicNoise.cs + var expectedValuesO45 = new List<(int X, int Y, float Result)> + { + (X: 0, Y: 0, Result: 0.1161f), (X: 0, Y: 1, Result: 0.1230f), (X: 0, Y: 2, Result: 0.1296f), (X: 0, Y: 3, Result: 0.1361f), (X: 0, Y: 4, Result: 0.1424f), (X: 0, Y: 5, Result: 0.1485f), (X: 0, Y: 6, Result: 0.1545f), (X: 0, Y: 7, Result: 0.1604f), (X: 0, Y: 8, Result: 0.1662f), (X: 0, Y: 9, Result: 0.1719f), + (X: 1, Y: 0, Result: 0.1229f), (X: 1, Y: 1, Result: 0.1293f), (X: 1, Y: 2, Result: 0.1354f), (X: 1, Y: 3, Result: 0.1414f), (X: 1, Y: 4, Result: 0.1472f), (X: 1, Y: 5, Result: 0.1528f), (X: 1, Y: 6, Result: 0.1583f), (X: 1, Y: 7, Result: 0.1637f), (X: 1, Y: 8, Result: 0.1690f), (X: 1, Y: 9, Result: 0.1741f), + (X: 2, Y: 0, Result: 0.1311f), (X: 2, Y: 1, Result: 0.1370f), (X: 2, Y: 2, Result: 0.1427f), (X: 2, Y: 3, Result: 0.1482f), (X: 2, Y: 4, Result: 0.1535f), (X: 2, Y: 5, Result: 0.1586f), (X: 2, Y: 6, Result: 0.1636f), (X: 2, Y: 7, Result: 0.1685f), (X: 2, Y: 8, Result: 0.1732f), (X: 2, Y: 9, Result: 0.1778f), + (X: 3, Y: 0, Result: 0.1407f), (X: 3, Y: 1, Result: 0.1462f), (X: 3, Y: 2, Result: 0.1514f), (X: 3, Y: 3, Result: 0.1564f), (X: 3, Y: 4, Result: 0.1612f), (X: 3, Y: 5, Result: 0.1658f), (X: 3, Y: 6, Result: 0.1703f), (X: 3, Y: 7, Result: 0.1746f), (X: 3, Y: 8, Result: 0.1788f), (X: 3, Y: 9, Result: 0.1828f), + (X: 4, Y: 0, Result: 0.1516f), (X: 4, Y: 1, Result: 0.1566f), (X: 4, Y: 2, Result: 0.1614f), (X: 4, Y: 3, Result: 0.1659f), (X: 4, Y: 4, Result: 0.1702f), (X: 4, Y: 5, Result: 0.1743f), (X: 4, Y: 6, Result: 0.1783f), (X: 4, Y: 7, Result: 0.1820f), (X: 4, Y: 8, Result: 0.1857f), (X: 4, Y: 9, Result: 0.1892f), + (X: 5, Y: 0, Result: 0.1637f), (X: 5, Y: 1, Result: 0.1683f), (X: 5, Y: 2, Result: 0.1726f), (X: 5, Y: 3, Result: 0.1766f), (X: 5, Y: 4, Result: 0.1805f), (X: 5, Y: 5, Result: 0.1841f), (X: 5, Y: 6, Result: 0.1875f), (X: 5, Y: 7, Result: 0.1907f), (X: 5, Y: 8, Result: 0.1938f), (X: 5, Y: 9, Result: 0.1968f), + (X: 6, Y: 0, Result: 0.1769f), (X: 6, Y: 1, Result: 0.1811f), (X: 6, Y: 2, Result: 0.1849f), (X: 6, Y: 3, Result: 0.1885f), (X: 6, Y: 4, Result: 0.1919f), (X: 6, Y: 5, Result: 0.1950f), (X: 6, Y: 6, Result: 0.1979f), (X: 6, Y: 7, Result: 0.2006f), (X: 6, Y: 8, Result: 0.2031f), (X: 6, Y: 9, Result: 0.2055f), + (X: 7, Y: 0, Result: 0.1912f), (X: 7, Y: 1, Result: 0.1949f), (X: 7, Y: 2, Result: 0.1984f), (X: 7, Y: 3, Result: 0.2015f), (X: 7, Y: 4, Result: 0.2044f), (X: 7, Y: 5, Result: 0.2070f), (X: 7, Y: 6, Result: 0.2093f), (X: 7, Y: 7, Result: 0.2115f), (X: 7, Y: 8, Result: 0.2135f), (X: 7, Y: 9, Result: 0.2153f), + (X: 8, Y: 0, Result: 0.2064f), (X: 8, Y: 1, Result: 0.2098f), (X: 8, Y: 2, Result: 0.2128f), (X: 8, Y: 3, Result: 0.2155f), (X: 8, Y: 4, Result: 0.2178f), (X: 8, Y: 5, Result: 0.2199f), (X: 8, Y: 6, Result: 0.2218f), (X: 8, Y: 7, Result: 0.2234f), (X: 8, Y: 8, Result: 0.2249f), (X: 8, Y: 9, Result: 0.2261f), + (X: 9, Y: 0, Result: 0.2226f), (X: 9, Y: 1, Result: 0.2256f), (X: 9, Y: 2, Result: 0.2281f), (X: 9, Y: 3, Result: 0.2304f), (X: 9, Y: 4, Result: 0.2323f), (X: 9, Y: 5, Result: 0.2339f), (X: 9, Y: 6, Result: 0.2352f), (X: 9, Y: 7, Result: 0.2363f), (X: 9, Y: 8, Result: 0.2372f), (X: 9, Y: 9, Result: 0.2378f), + + (X: 1123456, Y: -1123456, Result: 0.4196f), (X: 1123456, Y: -1123455, Result: 0.4052f), (X: 1123456, Y: -1123454, Result: 0.3917f), (X: 1123456, Y: -1123453, Result: 0.3779f), (X: 1123456, Y: -1123452, Result: 0.3627f), (X: 1123456, Y: -1123451, Result: 0.3485f), (X: 1123456, Y: -1123450, Result: 0.3328f), (X: 1123456, Y: -1123449, Result: 0.3184f), (X: 1123456, Y: -1123448, Result: 0.3039f), (X: 1123456, Y: -1123447, Result: 0.2881f), + (X: 1123457, Y: -1123456, Result: 0.4258f), (X: 1123457, Y: -1123455, Result: 0.4118f), (X: 1123457, Y: -1123454, Result: 0.3986f), (X: 1123457, Y: -1123453, Result: 0.3852f), (X: 1123457, Y: -1123452, Result: 0.3702f), (X: 1123457, Y: -1123451, Result: 0.3563f), (X: 1123457, Y: -1123450, Result: 0.3410f), (X: 1123457, Y: -1123449, Result: 0.3268f), (X: 1123457, Y: -1123448, Result: 0.3125f), (X: 1123457, Y: -1123447, Result: 0.2970f), + (X: 1123458, Y: -1123456, Result: 0.4318f), (X: 1123458, Y: -1123455, Result: 0.4182f), (X: 1123458, Y: -1123454, Result: 0.4053f), (X: 1123458, Y: -1123453, Result: 0.3922f), (X: 1123458, Y: -1123452, Result: 0.3776f), (X: 1123458, Y: -1123451, Result: 0.3640f), (X: 1123458, Y: -1123450, Result: 0.3489f), (X: 1123458, Y: -1123449, Result: 0.3350f), (X: 1123458, Y: -1123448, Result: 0.3211f), (X: 1123458, Y: -1123447, Result: 0.3058f), + (X: 1123459, Y: -1123456, Result: 0.4380f), (X: 1123459, Y: -1123455, Result: 0.4248f), (X: 1123459, Y: -1123454, Result: 0.4124f), (X: 1123459, Y: -1123453, Result: 0.3996f), (X: 1123459, Y: -1123452, Result: 0.3854f), (X: 1123459, Y: -1123451, Result: 0.3721f), (X: 1123459, Y: -1123450, Result: 0.3575f), (X: 1123459, Y: -1123449, Result: 0.3439f), (X: 1123459, Y: -1123448, Result: 0.3302f), (X: 1123459, Y: -1123447, Result: 0.3152f), + (X: 1123460, Y: -1123456, Result: 0.4433f), (X: 1123460, Y: -1123455, Result: 0.4306f), (X: 1123460, Y: -1123454, Result: 0.4185f), (X: 1123460, Y: -1123453, Result: 0.4061f), (X: 1123460, Y: -1123452, Result: 0.3923f), (X: 1123460, Y: -1123451, Result: 0.3794f), (X: 1123460, Y: -1123450, Result: 0.3651f), (X: 1123460, Y: -1123449, Result: 0.3518f), (X: 1123460, Y: -1123448, Result: 0.3385f), (X: 1123460, Y: -1123447, Result: 0.3238f), + (X: 1123461, Y: -1123456, Result: 0.4487f), (X: 1123461, Y: -1123455, Result: 0.4364f), (X: 1123461, Y: -1123454, Result: 0.4248f), (X: 1123461, Y: -1123453, Result: 0.4129f), (X: 1123461, Y: -1123452, Result: 0.3995f), (X: 1123461, Y: -1123451, Result: 0.3870f), (X: 1123461, Y: -1123450, Result: 0.3731f), (X: 1123461, Y: -1123449, Result: 0.3602f), (X: 1123461, Y: -1123448, Result: 0.3472f), (X: 1123461, Y: -1123447, Result: 0.3330f), + (X: 1123462, Y: -1123456, Result: 0.4532f), (X: 1123462, Y: -1123455, Result: 0.4414f), (X: 1123462, Y: -1123454, Result: 0.4302f), (X: 1123462, Y: -1123453, Result: 0.4187f), (X: 1123462, Y: -1123452, Result: 0.4058f), (X: 1123462, Y: -1123451, Result: 0.3937f), (X: 1123462, Y: -1123450, Result: 0.3802f), (X: 1123462, Y: -1123449, Result: 0.3677f), (X: 1123462, Y: -1123448, Result: 0.3551f), (X: 1123462, Y: -1123447, Result: 0.3412f), + (X: 1123463, Y: -1123456, Result: 0.4573f), (X: 1123463, Y: -1123455, Result: 0.4460f), (X: 1123463, Y: -1123454, Result: 0.4353f), (X: 1123463, Y: -1123453, Result: 0.4242f), (X: 1123463, Y: -1123452, Result: 0.4117f), (X: 1123463, Y: -1123451, Result: 0.4000f), (X: 1123463, Y: -1123450, Result: 0.3870f), (X: 1123463, Y: -1123449, Result: 0.3749f), (X: 1123463, Y: -1123448, Result: 0.3627f), (X: 1123463, Y: -1123447, Result: 0.3492f), + (X: 1123464, Y: -1123456, Result: 0.4612f), (X: 1123464, Y: -1123455, Result: 0.4505f), (X: 1123464, Y: -1123454, Result: 0.4403f), (X: 1123464, Y: -1123453, Result: 0.4297f), (X: 1123464, Y: -1123452, Result: 0.4178f), (X: 1123464, Y: -1123451, Result: 0.4066f), (X: 1123464, Y: -1123450, Result: 0.3941f), (X: 1123464, Y: -1123449, Result: 0.3824f), (X: 1123464, Y: -1123448, Result: 0.3706f), (X: 1123464, Y: -1123447, Result: 0.3576f), + (X: 1123465, Y: -1123456, Result: 0.4642f), (X: 1123465, Y: -1123455, Result: 0.4541f), (X: 1123465, Y: -1123454, Result: 0.4444f), (X: 1123465, Y: -1123453, Result: 0.4343f), (X: 1123465, Y: -1123452, Result: 0.4229f), (X: 1123465, Y: -1123451, Result: 0.4122f), (X: 1123465, Y: -1123450, Result: 0.4002f), (X: 1123465, Y: -1123449, Result: 0.3890f), (X: 1123465, Y: -1123448, Result: 0.3776f), (X: 1123465, Y: -1123447, Result: 0.3650f), + }; + + foreach (var (x, y, result) in expectedValuesO45) + { + var output = engineO45PX16PY99.Get(x, y); + Assert.That(output, Is.EqualTo(result).Within(0.00001f), $"The result {result} was expected (accepting a tolerance +/- 0.00001) for the input X={x}, Y={y}, but was {output}. Octave=45, px=16, py=99"); + } + + foreach (var (x, y, result) in expectedValuesO57) + { + var output = engineO57PX12PY16.Get(x, y); + Assert.That(output, Is.EqualTo(result).Within(0.00001f), $"The result {result} was expected (accepting a tolerance +/- 0.00001) for the input X={x}, Y={y}, but was {output}. Octave=57, px=12, py=16"); + } + } + } +}