/// <summary>
        /// Finds the horizontal tension to set the lowest point on the catenary.
        /// </summary>
        /// <param name="span"></param>
        /// <param name="w"></param>
        /// <param name="C">The specified vertical separation between the left
        ///                 support and the lowest point on the curve. Always positive.</param>
        /// <param name="tol"></param>
        /// <returns></returns>
        public static double SetClearance(Vector2 span, double w, double C, double tol)
        {
            if (tol <= 0)
            {
                tol = 1e-4;
            }
            C = Math.Max(C, MinSag);
            double H_init           = DoubleEx.Sqr(span.X) * w / (8 * C);
            Func <double, double> f = (H_) => - CenterPosition(span, w, H_).Y;

            if (f.Bisection(C, H_init, tol, out double H))
            {
                return(H);
            }
            return(H_init);
        }
        /// <summary>
        /// Calculates the horizontal tension needed to achieve specified maximum sag
        /// </summary>
        /// <param name="span">The span</param>
        /// <param name="w">The unit weight</param>
        /// <param name="D">The specified sag</param>
        /// <param name="tol">The tension tolerance for numeric solution (default 0.001)</param>
        /// <returns>The horizontal tension value</returns>
        public static double SetMaximumSag(Vector2 span, double w, double D, double tol)
        {
            if (tol <= 0)
            {
                tol = 1e-4;
            }
            D = Math.Max(D, MinSag);
            double H_init = DoubleEx.Sqr(span.X) * w / (8 * D);

            Func <double, double> f = (H_) => MaximumSag(span, w, H_);

            if (f.Bisection(D, H_init, tol, out double H))
            {
                return(H);
            }
            return(H_init);
        }
        /// <summary>
        /// Calculates the horizontal tension needed to achieve specified average tension
        /// </summary>
        /// <param name="span">The span</param>
        /// <param name="w">The unit weight</param>
        /// <param name="P">The specified average tension</param>
        /// <param name="tol">The tension tolerance for numeric solution (default 0.001)</param>
        /// <returns></returns>
        public static double SetAverageTension(Vector2 span, double w, double P, double tol)
        {
            if (tol <= 0)
            {
                tol = 1e-8;
            }
            P = Math.Max(P, MinTension);
            double σ      = span.X * w;
            double H_init = P / 2 + Math.Sqrt(DoubleEx.Sqr(P / 2) - DoubleEx.Sqr(σ) / 24);

            Func <double, double> f = (H_) => AverageTension(span, w, H_);

            if (f.Bisection(P, H_init, tol, out double H))
            {
                return(H);
            }
            return(H_init);
        }