Example #1
0
        // Open, nonuniform spline, that takes external knot vector.
        //
        // if bIsInteriorKnot, the knot array must have n-d-1 elements, the standard start/end
        //   sequences of #degree 0/1 knots will be automatically added by internal BSplineBasis.
        //
        // if !bIsInteriorKnot, the knot array must have n+d+1 elements and is used directly.
        //
        // eg for 7 control points degree-3 curve the full knot vector would be [0 0 0 0 a b c 1 1 1 1],
        //   and the interior knot vector would be [a b c].
        //
        // The knot elements must be nondecreasing.  Each element must be in [0,1]. Note that
        //   knot vectors can be arbitrary normalized by dividing by the largest knot, if
        //   you have a knot vector with values > 1
        //
        // loop=true duplicates the first control point to force loop closure, however this
        //   was broken in the WildMagic code because it didn't add a knot. I am not
        //   quite sure what to do here - a new non-1 knot value needs to be inserted for
        //   the previous last control point, somehow. Or perhaps the knot vector needs
        //   to be extended, ie the final degree-duplicate knots need value > 1?
        //
        // Currently to create a closed NURBS curve, the caller must handle this duplication
        //   themselves.
        public NURBSCurve2(int numCtrlPoints, Vector2d[] ctrlPoint, double[] ctrlWeight, int degree, bool loop,
                           double[] knot, bool bIsInteriorKnot = true)
            : base(0, 1)
        {
            if (numCtrlPoints < 2)
            {
                throw new Exception("NURBSCurve2(): only received " + numCtrlPoints + " control points!");
            }
            if (degree < 1 || degree > numCtrlPoints - 1)
            {
                throw new Exception("NURBSCurve2(): invalid degree " + degree);
            }

            // [RMS] loop mode doesn't work yet
            if (loop == true)
            {
                throw new Exception("NURBSCUrve2(): loop mode is broken?");
            }

            mLoop          = loop;
            mNumCtrlPoints = numCtrlPoints;
            mReplicate     = (loop ? 1 : 0);
            CreateControl(ctrlPoint, ctrlWeight);
            mBasis = new BSplineBasis(mNumCtrlPoints + mReplicate, degree, knot, bIsInteriorKnot);
        }
Example #2
0
        public BSplineBasis Clone()
        {
            var b2 = new BSplineBasis();

            b2.mNumCtrlPoints = this.mNumCtrlPoints;
            b2.mDegree        = this.mDegree;
            b2.mKnot          = (double[])this.mKnot.Clone();
            b2.mOpen          = this.mOpen;
            b2.mUniform       = this.mUniform;
            return(b2);
        }
Example #3
0
        // Construction and destruction. Internal copies of the
        // input arrays are made, so to dynamically change control points,
        // control weights, or knots, you must use the 'SetControlPoint',
        // 'GetControlPoint', 'SetControlWeight', 'GetControlWeight', and 'Knot'
        // member functions.

        // The homogeneous input points are (x,y,w) where the (x,y) values are
        // stored in the ctrlPoint array and the w values are stored in the
        // ctrlWeight array.  The output points from curve evaluations are of
        // the form (x',y') = (x/w,y/w).

        // Uniform spline.  The number of control points is n+1 >= 2.  The degree
        // of the spline is d and must satisfy 1 <= d <= n.  The knots are
        // implicitly calculated in [0,1].  If open is 'true', the spline is
        // open and the knots are
        //   t[i] = 0,               0 <= i <= d
        //          (i-d)/(n+1-d),   d+1 <= i <= n
        //          1,               n+1 <= i <= n+d+1
        // If open is 'false', the spline is periodic and the knots are
        //   t[i] = (i-d)/(n+1-d),   0 <= i <= n+d+1
        // If loop is 'true', extra control points are added to generate a closed
        // curve.  For an open spline, the control point array is reallocated and
        // one extra control point is added, set to the first control point
        // C[n+1] = C[0].  For a periodic spline, the control point array is
        // reallocated and the first d points are replicated.  In either case the
        // knot array is calculated accordingly.
        //
        // [RMS] "open" and "loop" are super-confusing here. Perhaps NURBSCurve2 should
        //   be refactored into several subclasses w/ different constructors, so that
        //   the naming makes sense?

        public NURBSCurve2(int numCtrlPoints, Vector2d[] ctrlPoint, double[] ctrlWeight, int degree, bool loop, bool open)
            : base(0, 1)
        {
            if (numCtrlPoints < 2)
            {
                throw new Exception("NURBSCurve2(): only received " + numCtrlPoints + " control points!");
            }
            if (degree < 1 || degree > numCtrlPoints - 1)
            {
                throw new Exception("NURBSCurve2(): invalid degree " + degree);
            }

            mLoop          = loop;
            mNumCtrlPoints = numCtrlPoints;
            mReplicate     = (loop ? (open ? 1 : degree) : 0);
            CreateControl(ctrlPoint, ctrlWeight);
            mBasis = new BSplineBasis(mNumCtrlPoints + mReplicate, degree, open);
        }