Example #1
0
        /// <summary>
        /// Determines the derivatives of a curve at a given parameter.<br/>
        /// <em>Corresponds to algorithm 3.2 from The NURBS Book by Piegl and Tiller.</em>
        /// </summary>
        /// <param name="curve">The curve object.</param>
        /// <param name="parameter">Parameter on the curve at which the point is to be evaluated.</param>
        /// <param name="numberDerivs">Integer number of basis functions - 1 = knots.length - degree - 2.</param>
        /// <returns>The derivatives.</returns>
        internal static List <Point4> CurveDerivatives(NurbsBase curve, double parameter, int numberDerivs)
        {
            List <Point4> curveHomogenizedPoints = curve.ControlPoints;

            int n             = curve.Knots.Count - curve.Degree - 2;
            int derivateOrder = numberDerivs < curve.Degree ? numberDerivs : curve.Degree;

            Point4[]      ck        = new Point4[numberDerivs + 1];
            int           knotSpan  = curve.Knots.Span(n, curve.Degree, parameter);
            List <Vector> derived2d = DerivativeBasisFunctionsGivenNI(knotSpan, parameter, curve.Degree, derivateOrder, curve.Knots);

            for (int k = 0; k < derivateOrder + 1; k++)
            {
                for (int j = 0; j < curve.Degree + 1; j++)
                {
                    double valToMultiply = derived2d[k][j];
                    Point4 pt            = curveHomogenizedPoints[knotSpan - curve.Degree + j];
                    for (int i = 0; i < pt.Size; i++)
                    {
                        ck[k][i] = ck[k][i] + (valToMultiply * pt[i]);
                    }
                }
            }
            return(ck.ToList());
        }
Example #2
0
        /// <summary>
        /// Inserts a collection of knots on a curve.<br/>
        /// <em>Implementation of Algorithm A5.4 of The NURBS Book by Piegl and Tiller.</em>
        /// </summary>
        /// <param name="curve">The curve object.</param>
        /// <param name="knotsToInsert">The set of knots.</param>
        /// <returns>A curve with refined knots.</returns>
        internal static NurbsBase KnotRefine(NurbsBase curve, IList <double> knotsToInsert)
        {
            if (knotsToInsert.Count == 0)
            {
                return(curve);
            }

            int           degree        = curve.Degree;
            List <Point4> controlPoints = curve.ControlPoints;
            KnotVector    knots         = curve.Knots;

            // Initialize common variables.
            int n = controlPoints.Count - 1;
            int m = n + degree + 1;
            int r = knotsToInsert.Count - 1;
            int a = knots.Span(degree, knotsToInsert[0]);
            int b = knots.Span(degree, knotsToInsert[r]);

            Point4[] controlPointsPost = new Point4[n + r + 2];
            double[] knotsPost         = new double[m + r + 2];

            // New control points.
            for (int i = 0; i < a - degree + 1; i++)
            {
                controlPointsPost[i] = controlPoints[i];
            }
            for (int i = b - 1; i < n + 1; i++)
            {
                controlPointsPost[i + r + 1] = controlPoints[i];
            }

            // New knot vector.
            for (int i = 0; i < a + 1; i++)
            {
                knotsPost[i] = knots[i];
            }
            for (int i = b + degree; i < m + 1; i++)
            {
                knotsPost[i + r + 1] = knots[i];
            }

            // Initialize variables for knot refinement.
            int g = b + degree - 1;
            int k = b + degree + r;
            int j = r;

            // Apply knot refinement.
            while (j >= 0)
            {
                while (knotsToInsert[j] <= knots[g] && g > a)
                {
                    controlPointsPost[k - degree - 1] = controlPoints[g - degree - 1];
                    knotsPost[k] = knots[g];
                    --k;
                    --g;
                }

                controlPointsPost[k - degree - 1] = controlPointsPost[k - degree];

                for (int l = 1; l < degree + 1; l++)
                {
                    int    ind  = k - degree + l;
                    double alfa = knotsPost[k + l] - knotsToInsert[j];

                    if (Math.Abs(alfa) < GSharkMath.Epsilon)
                    {
                        controlPointsPost[ind - 1] = controlPointsPost[ind];
                    }
                    else
                    {
                        alfa /= (knotsPost[k + l] - knots[g - degree + l]);
                        controlPointsPost[ind - 1] = (controlPointsPost[ind - 1] * alfa) +
                                                     (controlPointsPost[ind] * (1.0 - alfa));
                    }
                }

                knotsPost[k] = knotsToInsert[j];
                --k;
                --j;
            }

            return(new NurbsCurve(degree, knotsPost.ToKnot(), controlPointsPost.ToList()));
        }