Пример #1
0
 std::vector<::Movement::Spline::SplinePoint> MoveSpline::GetMidPoints()
 {
     std::vector<::Movement::Spline::SplinePoint> returnSpline;
     if (m_splinePoints.size() > 2)
     {
         for (uint32_t i = 1; i < m_splinePoints.size() - 1; ++i)
         {
             auto splineCopy = SplinePoint(m_splinePoints[i]);
             returnSpline.push_back(splineCopy);
         }
     }
     return returnSpline;
 }
Пример #2
0
SplinePoint SplinePoint::sampleBSpline(vector<SplinePoint*>& cps, double t, bool closed, int degree)
{
    if (cps.empty()) {
        UCBPrint("sampleBSpline", "need at least one control point");
        return SplinePoint();
    }


    // get into 0,1 range
    if (t > 1.0 || t < 0.0)
        t = fmod(t, 1.0);
    if (t < 0.0)
        t += 1.0;
    
    // adjust degree down as needed to get a curve, if too few control points and not on closed loop
    int numCPs = int(closed ? cps.size() + degree : cps.size());
    if (degree >= numCPs)
        degree = numCPs - 1;

    // rescale t to minSupport,maxSupport range
    double minSupport = degree;
    double maxSupport = numCPs;
    t = (1-t)*minSupport + t*maxSupport;

    // 'recursive' form of b-spline is done iteratively here
    SplinePoint *bases = new SplinePoint[degree+1];
    int k = (int)t;

    for (int i = 0; i <= degree; ++i) {
        bases[i] = *cps[(k - degree + i) % cps.size()];
    }

    for (int power = 1; power <= degree; ++power) {
        for (int i = 0; i <= degree - power; ++i) {
            int knot = k - degree + power + i;
            double u_i = (double)knot;
            double u_ipr1 = double(knot + degree - power + 1);
            double a = (t - u_i) / (u_ipr1 - u_i);
            bases[i] = SplinePoint::lerp(a, bases[i], bases[i+1]);
        }
    }

    SplinePoint result = bases[0];

    delete [] bases;

    return result;
}