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()); }