public Vector3D Derivative( double u, double v, DerivativeParameter parameter ) { double firstParameter, secondParameter; Func <int, Point3D[]> generator; switch (parameter) { case DerivativeParameter.U: generator = (i) => ArrayHelpers.GetColumn(ControlPoints, i); firstParameter = v; secondParameter = u; break; case DerivativeParameter.V: generator = (i) => ArrayHelpers.GetRow(ControlPoints, i); firstParameter = u; secondParameter = v; break; default: throw new ArgumentOutOfRangeException( nameof(parameter), parameter, null ); } var subpoints = new List <Point3D>(); for (var i = 0; i < 4; ++i) { subpoints.Add(BernsteinPolynomial.Evaluate3DPolynomial( generator(i), firstParameter )); } var derivative = BernsteinPolynomial.CalculateDerivative(subpoints); return((Vector3D)BernsteinPolynomial.Evaluate3DPolynomial( derivative, secondParameter )); }