public static NurbsPoint DeBoor(int p, List <NurbsPoint> controlPoints, decimal u, decimal[] knotVector) { if (u.AlmostEquals(0M)) { return(controlPoints.First()); } if (u.AlmostEquals(1M)) { return(controlPoints.Last()); } var k = FindSpan(u, knotVector); var s = NurbsLogic.CheckMultiplicity(knotVector, u); NurbsPoint point; if (u.GreaterThanOrEqualTo(knotVector[k]) && u.LessThan(knotVector[k + 1])) { var h = p - s; if (h == 0) { return(controlPoints[k - s]); } var points = new List <Point4D> [h + 1]; points[0] = controlPoints.ToPoint4DList(); for (var r = 1; r <= h; r++) { /*points[r] = new List<Point4D>(k - s + 1); * for (var i = 0; i <= k - s + 1; i++) * { * points[r].Add(new Point4D(-1, -1, -1, -1)); * }*/ points[r] = controlPoints.ToPoint4DList(); for (var i = k - p + r; i <= k - s; i++) { if (points[r - 1][i - 1] == null || points[r - 1][i] == null) { continue; } // ReSharper disable once InconsistentNaming var a_ir = (double)((u - knotVector[i]) / (knotVector[i + p - r + 1] - knotVector[i])); var x = ((1 - a_ir) * points[r - 1][i - 1].X) + (a_ir * points[r - 1][i].X); var y = ((1 - a_ir) * points[r - 1][i - 1].Y) + (a_ir * points[r - 1][i].Y); var z = ((1 - a_ir) * points[r - 1][i - 1].Z) + (a_ir * points[r - 1][i].Z); var weight = ((1 - a_ir) * points[r - 1][i - 1].Weight) + (a_ir * points[r - 1][i].Weight); points[r][i] = new Point4D(x, y, z, weight); } } point = points[h][k - s].ToNurbsPoint(); } else { // ReSharper disable once UnthrowableException throw new IndexOutOfRangeException("u not in [u_k, u_k+1)"); } return(point); }
public static int CheckMultiplicity(decimal[] knotVector, decimal knot) => knotVector.Count(u => knot.AlmostEquals(u));