如何 "join" 二次或三次样条曲线?

How can I "join" quadratic or cubic splines?

我有 2 个函数来计算样条曲线上的点,二次曲线或三次曲线:

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

    };

是否可以连接点数组的几条曲线?

我正在寻找具有此签名的函数:

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);
    }
}

}

我读到它需要插值,但我不确定...代码会是什么样子?我已经搜索过,但找不到相关问题和答案...

我看到有库,但我正在寻找更短的实现。

编辑:我试过这里的问题和答案,显然这就是我想要的:

Joining B-Spline segments in OpenGL / C++

代码不是很干净,但经过一些清理后,它确实可以工作。

我已经清理了这个答案Joining B-Spline segments in OpenGL / C++

这不是 Hermite 样条,Hermite 样条通过点,B 样条不通过。

这是有效的方法和结果

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;
}