/// <summary> /// Checks the validity of the input knot vector.<br/> /// Confirm the relations between degree (p), number of control points(n+1), and the number of knots (m+1).<br/> /// Refer to The NURBS Book (2nd Edition), p.50 for details.<br/> /// <br/> /// More specifically, this method checks if the knot vector is of the following structure:<br/> /// The knot knots must be non-decreasing and of length (degree + 1) * 2 or greater<br/> /// </summary> /// <param name="degree">The degree of the curve.</param> /// <param name="numberOfControlPts"></param> /// <returns>Whether the knots are valid.</returns> public bool IsValid(int degree, int numberOfControlPts) { if (Count == 0) { return(false); } if (Count < (degree + 1) * 2) { return(false); } // Check the formula: m = p + n + 1 if (numberOfControlPts + degree + 1 - Count != 0) { return(false); } for (int i = 0; i < Count; i++) { if (!GSharkMath.IsValidDouble(this[i])) { return(false); } } bool hasMultiplicity = Multiplicity(0) > 1 || Multiplicity(this.Count - 1) > 1; double rep = this[0]; for (int i = 0; i < Count; i++) { if (hasMultiplicity) { if (i < degree + 1) { if (Math.Abs(this[i] - rep) > GSharkMath.Epsilon) { return(false); } } if (i > Count - degree - 1 && i < Count) { if (Math.Abs(this[i] - rep) > GSharkMath.Epsilon) { return(false); } } } if (this[i] < rep - GSharkMath.Epsilon) { return(false); } rep = this[i]; } return(true); }
/// <summary> /// Converts normalized parameter to interval value, or pair of values. /// </summary> /// <param name="normalizedParameter">The normalized parameter between 0 and 1.</param> /// <returns>Interval parameter t0*(1.0-normalizedParameter) + t1*normalizedParameter.</returns> public double ParameterAt(double normalizedParameter) { return(!GSharkMath.IsValidDouble(normalizedParameter) ? GSharkMath.UnsetValue : (1.0 - normalizedParameter) * T0 + normalizedParameter * T1); }