1

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:

Joining B-Spline segments in OpenGL / C++

The code is not really clean but after some cleaning, it does work.

jokoon
  • 6,207
  • 11
  • 48
  • 85
  • ```vec2``` is a 2D point like ```(x, y)```? What represents ```a```, ```b```, ```c``` and ```d```? It's hard to understand your structure. – Carlos Adir Dec 03 '21 at 20:13
  • you need to be clearer about what you mean. what is the input and the output of spline_join? It takes a vector of points and a number of segments. What do the points mean. It outputs a vector of points -- what points is it outputting? Is it outputting *control points* of a spline? it is outputting points *on a spline*? etc. – jwezorek Dec 03 '21 at 20:16
  • Is [this](https://mathworld.wolfram.com/CubicSpline.html) what you are looking for? – Bob__ Dec 03 '21 at 20:20
  • @Bob__ yes! unfortunately I don't see how I can convert those equations into C code... – jokoon Dec 03 '21 at 20:42
  • @jwezorek I edited my question. – jokoon Dec 03 '21 at 20:46
  • i still don't get what you want. If you have an array of n points and n is 3k+1 where k is an integer then you can view this array as the control points of k cubic beziers concatenated together. You can find points on the beziers using the formula you give above. If you want it to be smooth then control points at bezier junctions must be colinear with the point of the junction. – jwezorek Dec 03 '21 at 21:39
  • @Bob__ 's link describes what I want. – jokoon Dec 03 '21 at 21:41
  • If you want the natural cubic spline from a given set of points then why did you title the question how to join splines? Anyway there is pseudocode for finding the natural cubic spline in the wikipedia article: https://en.wikipedia.org/wiki/Spline_(mathematics) – jwezorek Dec 03 '21 at 21:49
  • My question was more oriented towards something more C-like, those steps are not really pseudocode... I agree that my title is not clear but I'm not really sure how to describe what I want, but @Bob__ guessed it just fine. – jokoon Dec 03 '21 at 22:00
  • see [How can i produce multi point linear interpolation?](https://stackoverflow.com/a/30438865/2521214) and all the links in there (look for the point call sequence) – Spektre Dec 08 '21 at 09:04
  • this spline is weird, it sort of "oscillates". – jokoon Dec 09 '21 at 21:09
  • @jokoon kvadratic curves can be joined with the same 1st derivation on one side but that affects the other side so smooth joining of more than 2 curves is causing oscillations. Cubics does not have this disadvantage and are smooth at any number ... SPLINES has nothing to do with this its pure math problem as 3 control points does not hold enough freedom/information for the curve to hold 2 smooth joints – Spektre Dec 12 '21 at 09:23

1 Answers1

0

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;
}
jokoon
  • 6,207
  • 11
  • 48
  • 85