Пример #1
0
        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);
        }
Пример #2
0
 public static int CheckMultiplicity(decimal[] knotVector, decimal knot) => knotVector.Count(u => knot.AlmostEquals(u));