示例#1
0
        public IParametricCurve2d Clone()
        {
            NURBSCurve2 c2 = new NURBSCurve2();

            c2.mNumCtrlPoints = this.mNumCtrlPoints;
            c2.mCtrlPoint     = (Vector2d[])this.mCtrlPoint.Clone();
            c2.mCtrlWeight    = (double[])this.mCtrlWeight.Clone();
            c2.mLoop          = this.mLoop;
            c2.mBasis         = this.mBasis.Clone();
            c2.mReplicate     = this.mReplicate;
            c2.is_closed      = this.is_closed;
            return(c2);
        }
        // special case nurbs sampler. Computes a separate sampling of each unique knot interval
        // of the curve parameter space. Reasoning:
        //   1) computing Arc Length of an entire nurbs curve is quite slow if the curve has
        //      repeated knots. these become discontinuities which mean the numerical integrator
        //      has to do a lot of work. Instead we integrate between the discontinuities.
        //   2) by sampling per-knot-interval, we ensure we always place a sample at each knot
        //      value. If we don't do this, we can "miss" the sharp corners at duplicate knots.
        //   3) within each interval, we compute arc length and # of steps, but then sample
        //      by subdividing the T-interval. This is not precise arc-length sampling but
        //      is closer than uniform-T along the curve. And it means we don't have to
        //      do an arc-length evaluation for each point, which is very expensive!!
        public static VectorArray2d SampleNURBSHybrid(NURBSCurve2 curve, double fSpacing)
        {
            List <double> intervals = curve.GetParamIntervals();
            int           N         = intervals.Count - 1;

            VectorArray2d[] spans  = new VectorArray2d[N];
            int             nTotal = 0;

            for (int i = 0; i < N; ++i)
            {
                double t0   = intervals[i];
                double t1   = intervals[i + 1];
                double fLen = curve.GetLength(t0, t1);

                int    nSteps = Math.Max((int)(fLen / fSpacing) + 1, 2);
                double div    = 1.0 / nSteps;
                if (curve.IsClosed == false && i == N - 1)
                {
                    nSteps++;
                    div = 1.0 / (nSteps - 1);
                }

                VectorArray2d vec = new VectorArray2d(nSteps);
                for (int j = 0; j < nSteps; ++j)
                {
                    double a = (double)j * div;
                    double t = (1 - a) * t0 + (a) * t1;
                    vec[j] = curve.SampleT(t);
                }
                spans[i] = vec;
                nTotal  += nSteps;
            }

            VectorArray2d final  = new VectorArray2d(nTotal);
            int           iStart = 0;

            for (int i = 0; i < N; ++i)
            {
                final.Set(iStart, spans[i].Count, spans[i]);
                iStart += spans[i].Count;
            }

            return(final);
        }