/// <summary>
        /// Gets the calculated length.
        /// https://github.com/HTD/FastBezier
        /// </summary>
        /// <remarks>
        /// Integral calculation by Dave Eberly, slightly modified for the edge case with colinear control point.
        /// See: http://www.gamedev.net/topic/551455-length-of-a-generalized-quadratic-bezier-curve-in-3d/
        /// </remarks>
        public static double Length(GPoint P0, GPoint P1, GPoint P2)
        {
            if (P0 == P2)
            {
                if (P0 == P1)
                {
                    return(0.0);
                }
                return(P0.Distance(P1));
            }
            if (P1 == P0 || P1 == P2)
            {
                return(P0.Distance(P2));
            }

            GPoint A0 = P1 - P0;
            GPoint A1 = P0 - 2.0 * P1 + P2;

            if (!A1.Zero)
            {
                double c      = 4.0 * A1.DotProduct(A1);
                double b      = 8.0 * A0.DotProduct(A1);
                double a      = 4.0 * A0.DotProduct(A0);
                double q      = 4.0 * a * c - b * b;
                double twoCpB = 2.0 * c + b;
                double sumCBA = c + b + a;
                var    l0     = (0.25 / c) * (twoCpB * Math.Sqrt(sumCBA) - b * Math.Sqrt(a));
                double k1     = 2.0 * Math.Sqrt(c * sumCBA) + twoCpB;
                double k2     = 2.0 * Math.Sqrt(c * a) + b;
                if ((k1 <= 0.0) || (k2 <= 0.0))
                {
                    return(l0);
                }

                var l1 = (q / (8.0 * Math.Pow(c, 1.5))) * (Math.Log(k1) - Math.Log(k2));
                return(l0 + l1);
            }
            else
            {
                return(2.0 * A0.Length());
            }
        }