public void TestCalculateApplyDeltaRoundtrip()
    {
        var initial = new Swing(0.2f, 0.1f);
        var final   = new Swing(-0.3f, 0.4f);

        var delta          = Swing.CalculateDelta(initial, final);
        var roundtripFinal = Swing.ApplyDelta(initial, delta);

        MathAssert.AreEqual(final, roundtripFinal, Acc);
    }
    public void FuzzCalculateDelta()
    {
        var rnd = new Random(0);

        for (int i = 0; i < 1000; ++i)
        {
            var initial = RandomUtil.Swing(rnd);
            var final   = RandomUtil.Swing(rnd);
            var delta   = Swing.CalculateDelta(initial, final);

            var twistAxis            = CartesianAxis.X;
            var initialAndDeltaPoint = delta.Transform(twistAxis, initial.TransformTwistAxis(twistAxis));
            var finalPoint           = final.TransformTwistAxis(twistAxis);
            Assert.AreEqual(1, Vector3.Dot(initialAndDeltaPoint, finalPoint), 1e-3f);
        }
    }
    public void TestCalculateDeltaEdgeCases()
    {
        var rnd   = new Random(1);
        var swing = RandomUtil.Swing(rnd);
        var axis  = swing.Axis;
        var angle = swing.Angle;

        var zero       = Swing.Zero;
        var full       = new Swing(axis.X, axis.Y);
        var complement = Swing.AxisAngle(axis.X, axis.Y, MathUtil.Pi - angle);

        MathAssert.AreEqual(zero, Swing.CalculateDelta(zero, zero), 1e-3f);
        MathAssert.AreEqual(full, Swing.CalculateDelta(zero, full), 1e-3f);
        MathAssert.AreEqual(zero, Swing.CalculateDelta(full, full), 1e-3f);
        MathAssert.AreEqual(complement, Swing.CalculateDelta(swing, full), 1e-3f);
        MathAssert.AreEqual(swing, Swing.CalculateDelta(complement, full), 1e-3f);
    }