public static CylinderComponent[] CreateNonLinear(int count, double r1, double r2, double r3)
        {
            Contract.Requires(count >= 2);
            Contract.Requires(r1 > 0);
            Contract.Requires(r2 > 0);
            Contract.Requires(r3 > 0);
            Contract.Ensures(Contract.Result <CylinderComponent[]>() != null);
            Contract.Ensures(Contract.Result <CylinderComponent[]>().Length == count);
            Contract.Ensures(Contract.Result <CylinderComponent[]>()[0].Radius == r1);
            Contract.Ensures(NumericUtils.AreRelativeClose(Contract.Result <CylinderComponent[]>().Last().Radius, r3, maxFraction: 1E-5));

            // coefficients of a quadratic function r(t) = a + bt + ct² such that
            // r(0) = r1, r(0.5) = r2, r(1) = r3.
            var a = r1;
            var b = -r3 + 4 * r2 - 3 * r1;
            var c = 2 * r3 - 4 * r2 + 2 * r1;

            // create a set of radii according to the above function.
            var resultQuery =
                from i in Enumerable.Range(0, count)
                let t                 = i / (double)(count - 1)
                                let r = a + b * t + c * t * t
                                        select new CylinderComponent(r, t);

            return(resultQuery.ToArray());
        }