Home > Mobile >  How can I "join" quadratic or cubic splines?
How can I "join" quadratic or cubic splines?

Time:12-12

I have 2 function to either calculate a point on a spline, quadratic or cubic:

struct vec2 {float x, y;};

vec2 spline_quadratic(vec2 & a, vec2 & b, vec2 & c, float t) {
    return {
        (1 - t) * (1 - t) * p1.x   2 * (1 - t) * t * p2.x   t * t * p3.x,
        (1 - t) * (1 - t) * p1.y   2 * (1 - t) * t * p2.y   t * t * p3.y
    };
}
vec2 spline_cubic(vec2 & a, vec2 & b, vec2 & c, vec2 & d, float t){

    return {
    //B(t) = (1-t)**3 p0   3(1 - t)**2 t P1   3(1-t)t**2 P2   t**3 P3

        (1 - t) * (1 - t) * (1 - t) * p1.x   3 * (1 - t) * (1 - t) * t * p2.x   3 * (1 - t) * t * t * p3.x   t * t * t * p4.x,
        (1 - t) * (1 - t) * (1 - t) * p1.y   3 * (1 - t) * (1 - t) * t * p2.y   3 * (1 - t) * t * t * p3.y   t * t * t * p4.y

    };

Is it possible to join several curves of an array of points?

I'm looking to make a function that has this signature:

vector<vec2> spline_join(vector<vec2> & points, int segments = 16){
vector<vec2> spline_points;
for(int i = 0; i < points.size()-2;   i){
    for(int div = 0; div < segments;   div){
    spline_points.push_back(spline_quadratic(points[0], points[1], points[2], 1.f/segments);
    }
}

}

I've read that it requires interpolation, but I'm not sure... What would the code look like? I've searched and I can't find relevant question and answers...

I've seen there are libraries, but I'm looking for a shorter implementation.

Edit: I've tried the question and answer here and apparently this is what I want:

result

I've cleaned this answer Joining B-Spline segments in OpenGL / C

This is not an Hermite spline, an hermite spline passes through the points, a B-spline does not.

Here is what worked and the result

float B0(float u) {
    //return  float(pow(u - 1, 3) / 6.0);
    // (1-t)*(1-t)*(1-t)/6.f
    return  float(pow(1-u, 3) / 6.0);
}

float B1(float u) {
    return float((3 * pow(u, 3) - 6 * pow(u, 2)   4) / 6.0);
    // (3 * t * t * t - 6 * t * t   4) / 6
}

float B2(float u) {
    return float((-3 * pow(u, 3)   3 * pow(u, 2)   3 * u   1) / 6.0);
    // (-3 * t * t * t   3 * t * t   3 * t   1) / 6
}

float B3(float u) {
    return float(pow(u, 3) / 6.0);
    // t * t * t / 6
}

vector<Vec2> computeBSpline(vector<Vec2>& points) {
    vector<Vec2> result;
    int MAX_STEPS = 100;
    int NUM_OF_POINTS = points.size();
    for (int i = 0; i < NUM_OF_POINTS - 3; i  )
    {
        //cout << "Computing for P" << i << " P " << i   1 << " P " << i   2 << " P " << i   3 << endl;
        for (int j = 0; j <= MAX_STEPS; j  )
        {

            float u = float(j) / float(MAX_STEPS);

            float Qx =
                B0(u) * points[i].x
                  B1(u) * points[i   1].x
                  B2(u) * points[i   2].x
                  B3(u) * points[i   3].x;

            float Qy =
                B0(u) * points[i].y
                  B1(u) * points[i   1].y
                  B2(u) * points[i   2].y
                  B3(u) * points[i   3].y;

            result.push_back({ Qx, Qy });

            //cout << count << '(' << Qx << ", " << Qy << ")\n";
        }
    }
    return result;
}
  • Related