/// <summary> /// Adds a new Bezier curve segment to spline. The new segment and the previous last segment will have a /// control point added between the last two and the first two control points respectively, to ensure spline /// continuity between segments. /// </summary> /// <param name="controlPoints">Control points of new Bezier curve. If this exceeds the maximum specified /// upon spline instantiation, they will be split up accordingly.</param> public void AddSegment(Vector3[] controlPoints) { // Cut up controlpoints to targetN degree bezier if necessary by calling AddSegment recursively if (controlPoints.Length >= (maximumDegree + minimumDegree - 1)) { int currN; if (controlPoints.Length >= maximumDegree) { currN = maximumDegree; } else { currN = controlPoints.Length; } // create two selections of control points 6: 1 2 3 4 4 5 6 Vector3[] sel1 = new Vector3[currN]; Vector3[] sel2 = new Vector3[controlPoints.Length - (currN - 1)]; for (int i = 0; i < currN; i++) { sel1[i] = controlPoints[i]; } for (int i = 0; i < sel2.Length; i++) { sel2[i] = controlPoints[i + currN - 1]; } this.AddSegment(sel1); this.AddSegment(sel2); } else { // Add segment if (nCurveSegments == 0) { curveSegments.Add(new BezierCurveSegment(controlPoints, minimumDegree)); startPoint = curveSegments[0].startPoint; } else { // Ensure continuity between new and old segment List <BezierCurveSegment> segments = EnsureContinuityBetweenTwoSegmentsByMoving(curveSegments[nCurveSegments - 1], new BezierCurveSegment(controlPoints, minimumDegree)); // Replace pre-segment curveSegments[nCurveSegments - 1] = segments[0]; //nControlPoints++; // Add post as new segment curveSegments.Add(segments[1]); } // Increment counters and recreate frame nCurveSegments++; nControlPoints += curveSegments[curveSegments.Count - 1].nControlPoints; endPoint = curveSegments[nCurveSegments - 1].endPoint; this.rotationMinimizingFrames = new RotationMinimizingFrames(NSamplesToUse, this.GetPointOnSpline, this.GetTangentToPointOnSpline); } }
/// <summary> /// Initializes a new instance of <see cref="Spline"/> class. /// </summary> /// <param name="controlPoints">Optional Bezier control points for first curve segment.</param> /// <param name="maximumDegree">Maximum degree of all Bezier curve segments for this spline. /// If new curve segments' degree exceeds this maximum, they will be split up and form separate curve segments.</param> /// <param name="minimumDegree">Minimum degree of all Bezier curve segments for this spline. /// If new curve segments' degree fall below this minimum, additional control points will be added between last two points.</param> public Spline(Vector3[] controlPoints = null, int maximumDegree = 4, int minimumDegree = 4, int NSamplesPerControlPoint = 20) { nControlPoints = 0; nCurveSegments = 0; curveSegments = new List <BezierCurveSegment>(); this.maximumDegree = maximumDegree; this.minimumDegree = minimumDegree; this.NSamplesPerControlPoint = NSamplesPerControlPoint; if (controlPoints != null) { this.AddSegment(controlPoints); this.rotationMinimizingFrames = new RotationMinimizingFrames(NSamplesToUse, this.GetPointOnSpline, this.GetTangentToPointOnSpline); } DefaultGetNormalAtT = this.GetMinimallyRotatingNormalToPointOnSpline; }
/// <summary> /// Initializes a new instance of the <see cref="NDegreeBezierCurve"/> class. /// </summary> /// <param name="p">Control points of Bezier curve, of any length (typically 4). Note: very high degree can become unstable..</param> public NDegreeBezierCurve(Vector3[] p, int nSamplesPerControlPoint = 20) { this.p = p; this.n = p.Length - 1; // p0,p1,p2,pN this.rotationMinimizingFrames = new RotationMinimizingFrames(nSamplesPerControlPoint * n, this.GetPointOnCurve, this.GetTangentToPointOnCurve); }