/// <summary> /// Constructs a nurbs curve representation of this polyline. /// </summary> /// <returns>A Nurbs curve shaped like this polyline.</returns> private void ToNurbs() { double lengthSum = 0; List <double> weights = new List <double>(); KnotVector knots = new KnotVector { 0, 0 }; List <Point4> ctrlPts = new List <Point4>(); for (int i = 0; i < ControlPointLocations.Count - 1; i++) { lengthSum += Segments[i].Length; knots.Add(lengthSum); weights.Add(1.0); ctrlPts.Add(new Point4(ControlPointLocations[i], 1.0)); } knots.Add(lengthSum); weights.Add(1.0); ctrlPts.Add(new Point4(ControlPointLocations.Last(), 1.0)); Weights = weights; Knots = knots.Normalize(); Degree = 1; ControlPoints = ctrlPts; }
public void It_Throws_An_Exception_If_Input_Knot_Vector_Is_Empty() { // Assert KnotVector knots = new KnotVector(); // Act Func <KnotVector> func = () => knots.Normalize(); // Arrange func.Should().Throw <Exception>().WithMessage("Input knot vector cannot be empty"); }
public void It_Returns_A_Normalized_Knot_Vector() { // Arrange KnotVector knots = new KnotVector { -5, -5, -3, -2, 2, 3, 5, 5 }; KnotVector knotsExpected = new KnotVector { 0.0, 0.0, 0.2, 0.3, 0.7, 0.8, 1.0, 1.0 }; // Act KnotVector normalizedKnots = knots.Normalize(); // Assert normalizedKnots.Should().BeEquivalentTo(knotsExpected); }
/// <summary> /// Internal constructor used to validate the NURBS surface. /// </summary> /// <param name="degreeU">The degree in the U direction.</param> /// <param name="degreeV">The degree in the V direction.</param> /// <param name="knotsU">The knotVector in the U direction.</param> /// <param name="knotsV">The knotVector in the V direction.</param> /// <param name="controlPts">Two dimensional array of points.</param> internal NurbsSurface(int degreeU, int degreeV, KnotVector knotsU, KnotVector knotsV, List <List <Point4> > controlPts) { if (controlPts == null) { throw new ArgumentNullException("Control points array connot be null!"); } if (degreeU < 1) { throw new ArgumentException("DegreeU must be greater than 1!"); } if (degreeV < 1) { throw new ArgumentException("DegreeV must be greater than 1!"); } if (knotsU == null) { throw new ArgumentNullException("KnotU cannot be null!"); } if (knotsV == null) { throw new ArgumentNullException("KnotV cannot be null!"); } if (knotsU.Count != controlPts.Count() + degreeU + 1) { throw new ArgumentException("Points count + degreeU + 1 must equal knotsU count!"); } if (knotsV.Count != controlPts.First().Count() + degreeV + 1) { throw new ArgumentException("Points count + degreeV + 1 must equal knotsV count!"); } if (!knotsU.IsValid(degreeU, controlPts.Count())) { throw new ArgumentException("Invalid knotsU!"); } if (!knotsV.IsValid(degreeV, controlPts.First().Count())) { throw new ArgumentException("Invalid knotsV!"); } DegreeU = degreeU; DegreeV = degreeV; KnotsU = (Math.Abs(knotsU.GetDomain(degreeU).Length - 1.0) > GSharkMath.Epsilon) ? knotsU.Normalize() : knotsU; KnotsV = (Math.Abs(knotsV.GetDomain(degreeV).Length - 1.0) > GSharkMath.Epsilon) ? knotsV.Normalize() : knotsV; Weights = Point4.GetWeights2d(controlPts); ControlPointLocations = Point4.PointDehomogenizer2d(controlPts); ControlPoints = controlPts; DomainU = new Interval(KnotsU.First(), KnotsU.Last()); DomainV = new Interval(KnotsV.First(), KnotsV.Last()); }