예제 #1
0
        public static List <NurbsCurve> CurveSplit(NurbsCurve curve, double u)
        {
            int           degree        = curve.Degree;
            List <Vector> controlPoints = curve.ControlPoints;
            KnotArray     knots         = curve.Knots;

            List <double> knots_to_insert = new List <double>();

            for (int i = 0; i <= degree; i++)
            {
                knots_to_insert.Add(u);
            }

            NurbsCurve refinedCurve = Modify.CurveKnotRefine(curve, knots_to_insert);

            int s = Eval.KnotSpan(degree, u, knots);

            KnotArray knots0 = (KnotArray)refinedCurve.Knots.ToList().GetRange(0, s + degree + 2);
            KnotArray knots1 = (KnotArray)refinedCurve.Knots.ToList().GetRange(0, s + 1);

            List <Vector> cpts0 = refinedCurve.ControlPoints.GetRange(0, s + 1);
            List <Vector> cpts1 = refinedCurve.ControlPoints.GetRange(0, s + 1);

            return(new List <NurbsCurve>()
            {
                new NurbsCurve(degree, knots0, cpts0), new NurbsCurve(degree, knots1, cpts1)
            });
        }
예제 #2
0
        /// <summary>
        /// Check whether a given list is a valid NURBS knot vector. This also checks the validity of the end points.
        /// More specifically, this method checks if the knot vector is of the following structure:
        /// The knot vector must be non-decreasing and of length (degree + 1) * 2 or greater
        /// [ (degree + 1 copies of the first knot), internal non-decreasing knots, (degree + 1 copies of the last knot) ]
        /// </summary>
        /// <param name="vector">The knot vector to test</param>
        /// <param name="degree">The degree</param>
        /// <returns>Whether the array is a valid knot vector or knot</returns>
        public static bool IsValidKnotVector(KnotArray vector, int degree)
        {
            if (vector.Count == 0)
            {
                return(false);
            }
            if (vector.Count < (degree + 1) * 2)
            {
                return(false);
            }
            var rep = vector.First();

            for (int i = 0; i <= degree + 1; i++)
            {
                if (Math.Abs(vector[i] - rep) > Constants.EPSILON)
                {
                    return(false);
                }
            }
            rep = vector.Last();
            for (int i = vector.Count - degree - 1; i <= vector.Count; i++)
            {
                if (Math.Abs(vector[i] - rep) > Constants.EPSILON)
                {
                    return(false);
                }
            }
            return(IsNonDecreasing(vector));
        }
예제 #3
0
        /// <summary>
        /// find the span on the knot list of the given parameter, (corresponds to algorithm 2.1 from the NURBS book, piegl & Tiller 2nd edition)
        ///
        /// </summary>
        /// <param name="n">integer number of basis functions - 1 = knots.length - degree - 2</param>
        /// <param name="degree">integer degree of function</param>
        /// <param name="u">parameter</param>
        /// <param name="knots">array of nondecreasing knot values</param>
        /// <returns>the index of the knot span</returns>
        public static int KnotSpanGivenN(int n, int degree, double u, KnotArray knots)
        {
            if (u > knots[n + 1] - Constants.EPSILON)
            {
                return(n);
            }

            if (u < knots[degree] + Constants.EPSILON)
            {
                return(degree);
            }

            var low  = degree;
            var high = n + 1;
            int mid  = (int)Math.Floor((decimal)(low + high) / 2);

            while (u < knots[mid] || u >= knots[mid + 1])
            {
                if (u < knots[mid])
                {
                    high = mid;
                }
                else
                {
                    low = mid;
                }

                mid = (int)Math.Floor((decimal)(low + high) / 2);
            }

            return(mid);
        }
예제 #4
0
 public NurbsSurface(int degreeU, int degreeV, KnotArray knotsU, KnotArray knotsV, List <List <Point> > controlPoints)
 {
     DegreeU       = degreeU;
     DegreeV       = degreeV;
     KnotsU        = knotsU;
     KnotsV        = knotsV;
     ControlPoints = controlPoints;
 }
예제 #5
0
 public Volume(int degreeU, int degreeV, int degreeW, KnotArray knotsU, KnotArray knotsV, KnotArray knotsW, List <List <List <Point> > > controlPoints)
 {
     DegreeU       = degreeU;
     DegreeV       = degreeV;
     DegreeW       = degreeW;
     KnotsU        = knotsU;
     KnotsV        = knotsV;
     KnotsW        = knotsW;
     ControlPoints = controlPoints;
 }
예제 #6
0
        public static NurbsCurve Polyline(List <Vector> points)
        {
            KnotArray knots = new KnotArray()
            {
                0.0, 0.0
            };
            double lsum = 0.0;

            for (int i = 0; i < points.Count - 1; i++)
            {
                lsum += Constants.DistanceTo(points[i], points[i + 1]);
                knots.Add(lsum);
            }
            knots.Add(lsum);
            var weights = points.Select(x => 1.0).ToList();

            points.ForEach(x => weights.Add(1.0));
            return(new NurbsCurve(1, knots, Eval.Homogenize1d(points, weights)));
        }
예제 #7
0
        public static NurbsCurve RationalBezierCurve(List <Vector> controlPoints, List <double> weights = null)
        {
            var degree = controlPoints.Count - 1;
            var knots  = new KnotArray();

            for (int i = 0; i < degree + 1; i++)
            {
                knots.Add(0.0);
            }
            for (int i = 0; i < degree + 1; i++)
            {
                knots.Add(1.0);
            }
            if (weights == null)
            {
                weights = Sets.RepeatData(1.0, controlPoints.Count);
            }
            return(new NurbsCurve(degree, knots, Eval.Homogenize1d(controlPoints, weights)));

            weights = Constants.Rep(controlPoints.Count, 1.0);
            //return new NurbsCurveData(degree, knots, Eval.Homogenize1d(controlPoints, weights));
            return(null);
        }
예제 #8
0
        /// <summary>
        /// Insert a collectioin of knots on a curve
        /// corresponds to Algorithm A5.2 (Piegl & Tiller)
        /// </summary>
        /// <param name="curve"></param>
        /// <param name="knotsToInsert"></param>
        /// <returns></returns>
        public static NurbsCurve CurveKnotRefine(NurbsCurve curve, List <double> knotsToInsert)
        {
            if (knotsToInsert.Count == 0)
            {
                return(curve);
            }

            int           degree        = curve.Degree;
            List <Vector> controlPoints = curve.ControlPoints;
            KnotArray     knots         = curve.Knots;

            int           n = controlPoints.Count - 1;
            int           m = n + degree + 1;
            int           r = knotsToInsert.Count - 1;
            int           a = Eval.KnotSpan(degree, knotsToInsert[0], knots);
            int           b = Eval.KnotSpan(degree, knotsToInsert[r], knots);
            List <Vector> controlPoints_post = new List <Vector>();
            KnotArray     knots_post         = new KnotArray();

            //new control points
            for (int i = 0; i <= a - degree; i++)
            {
                controlPoints_post[i] = controlPoints[i];
            }

            for (int i = b - 1; i <= n; i++)
            {
                controlPoints_post[i + r + 1] = controlPoints[i];
            }

            //new knot vector
            for (int i = 0; i <= a; i++)
            {
                knots_post[i] = knots[i];
            }

            for (int i = b + degree; i <= m; i++)
            {
                knots_post[i + r + 1] = knots[i];
            }

            int g = b + degree + 1;
            int k = b + degree + r;
            int j = r;

            while (j >= 0)
            {
                while (knotsToInsert[j] <= knots[g] && g > a)
                {
                    controlPoints_post[k - degree - 1] = controlPoints[g - degree - 1];
                    knots_post[k] = knots[g];
                    k--;
                    g--;
                }

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

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

                    if (Math.Abs(alfa) < Constants.EPSILON)
                    {
                        controlPoints_post[ind - 1] = controlPoints_post[ind];
                    }
                    else
                    {
                        alfa = alfa / (knots_post[k + 1] - knots[g - degree + 1]);
                        controlPoints_post[ind - 1] = (Vector)Constants.Addition(Constants.Multiplication(controlPoints_post[ind - 1], alfa), Constants.Multiplication(controlPoints_post[ind], 1.0 - alfa));
                    }
                }

                knots_post[k] = knotsToInsert[j];
                k             = k - 1;
                j--;
            }


            return(new NurbsCurve(degree, knots_post, controlPoints_post));
        }
예제 #9
0
 /// <summary>
 /// Reverse a knot vector
 /// </summary>
 /// <param name="knots">An array of knots</param>
 /// <returns>The reversed array of knots</returns>
 public static KnotArray KnotsReverse(KnotArray knots)
 {
     throw new NotImplementedException();
 }
예제 #10
0
 public NurbsCurve(int degree, KnotArray knots, List <Vector> controlPoints)
 {
     Degree        = degree;
     ControlPoints = controlPoints;
     Knots         = knots;
 }
예제 #11
0
 /// <summary>
 /// Find the span on the knot Array without supplying n
 /// </summary>
 /// <param name="degree">integer degree of function</param>
 /// <param name="u">float parameter</param>
 /// <param name="knots">array of nondecreasing knot values</param>
 /// <returns></returns>
 public static int KnotSpan(int degree, double u, KnotArray knots)
 {
     return(KnotSpanGivenN(knots.Count - degree - 2, degree, u, knots));
 }