Ejemplo n.º 1
0
        public static IEnumerable <PrimitiveBezier> SplineToBezierCurves(Spline spline)
        {
            if (spline == null)
            {
                throw new ArgumentNullException(nameof(spline));
            }

            var expectedIdenticalKnots = spline.Degree + 1;
            var builder = new SplineBuilder(spline.Degree, spline.ControlPoints, spline.KnotValues);

            for (int offset = 0; ; offset++)
            {
                // get next set of values
                var values = builder.KnotValues.Skip(offset * expectedIdenticalKnots).Take(expectedIdenticalKnots).ToList();

                if (values.Count == 0 && builder.KnotValues.Count() % expectedIdenticalKnots == 0)
                {
                    // done
                    break;
                }

                var expectedValue = values[0];
                int missingValueCount;
                if (values.Count < expectedIdenticalKnots)
                {
                    // not enough values
                    missingValueCount = expectedIdenticalKnots - values.Count;
                }
                else if (values.Count < expectedIdenticalKnots || values.Any(v => v != expectedValue))
                {
                    // not all the same
                    missingValueCount = expectedIdenticalKnots - values.Count(v => v == expectedValue);
                }
                else
                {
                    missingValueCount = 0;
                }

                for (int i = 0; i < missingValueCount; i++)
                {
                    builder.InsertKnot(expectedValue);
                }
            }

            var points = builder.ControlPoints.ToList();
            var curves = new List <PrimitiveBezier>();

            for (int startIndex = 0; startIndex < points.Count; startIndex += expectedIdenticalKnots)
            {
                var curve = PrimitiveBezier.FromPoints(points, startIndex, expectedIdenticalKnots);
                curves.Add(curve);
            }

            return(curves);
        }
Ejemplo n.º 2
0
        public Spline(int degree, IEnumerable <Point> controlPoints, IEnumerable <double> knotValues, CadColor?color = null, object tag = null)
            : base(color, tag)
        {
            if (controlPoints == null)
            {
                throw new ArgumentNullException(nameof(controlPoints));
            }

            if (knotValues == null)
            {
                throw new ArgumentNullException(nameof(knotValues));
            }

            if (degree != 3)
            {
                throw new NotImplementedException("Only cubic splines are currently supported.");
            }

            Degree        = degree;
            ControlPoints = controlPoints.ToArray();
            KnotValues    = knotValues.ToArray();

            if (KnotValues.Length != ControlPoints.Length + Degree + 1)
            {
                throw new InvalidOperationException("The number of knot values must be one greater than the sum of the number of control points and the degree of the curve.");
            }

            _snapPoints = new[]
            {
                new EndPoint(ControlPoints[0]),
                new EndPoint(ControlPoints[ControlPoints.Length - 1])
            };

            _beziers    = SplineBuilder.SplineToBezierCurves(this).ToArray();
            BoundingBox = BoundingBox.Includes(_beziers.Select(b => b.GetBoundingBox()));
        }