2

I'm trying to write a program to generate a curve in C++ to plot a B-Spline curve. This is what my code looks like.

void drawBSplineCurve(vector<point> poly)
{
    int n, d;
    cout << "Enter degree of curve: ";
    cin >> d;
    n = poly.size();
    vector<double> uVec;
    int i;
    for(i=0;i<n+d;i++)
    {
        uVec.push_back(((double)i)/(n+d-1));
    }
    double x, y, basis, u;
    for(u=0;u<=1;u+=0.0001)
    {
        x = 0;
        y = 0;
        for(i=0;i<poly.size();i++)
        {
            basis = blend(uVec, u, i, d);
            x += basis*poly[i].x;
            y += basis*poly[i].y;
        }
        putpixel(roundOff(x), roundOff(y), YELLOW);
    }
}

double blend(vector<double> &uVec, double u, int k, int d)
{
    if(d==1)
    {
        if(uVec[k]<=u && u<uVec[k+1])
            return 1;
        return 0;
    }
    double b;
    b = ((u-uVec[k])/(uVec[k+d-1]-uVec[k])*blend(uVec, u, k, d-1)) + ((uVec[k+d]-u)/(uVec[k+d]-uVec[k+1])*blend(uVec, u, k+1, d-1));
    return b;
}

However, as you can see from my output, the curve, for some reason, tends to start and end at the origin (y-axis is inverted). Any help on the reason for this would be appreciated. Thanks :D

Output

Spektre
  • 49,595
  • 11
  • 110
  • 380
naman1901
  • 305
  • 4
  • 16
  • Which graphics library do you use? – πάντα ῥεῖ Oct 22 '16 at 13:58
  • This is `graphics.h` of old. We're taught to use this in college, sadly. – naman1901 Oct 22 '16 at 13:59
  • I think your `uvec` is wrong. Shouldn't it have repeated values at the beginning and the end? Furthermore, watch out for division by zero in `blend()`. – Nico Schertler Oct 22 '16 at 14:00
  • @NicoSchertler Why should my `uVec` have repeated values? Also, wouldn't division by zero make my program crash, as I haven't handled the exception? – naman1901 Oct 22 '16 at 14:03
  • Are you able to add the co-ords of the points used to generate the shown image to your question? While not absolutely necessary, they may make debugging a little faster - it's only 7 pairs after all. – enhzflep Oct 22 '16 at 14:04
  • @enhzflep I'm using my mouse for input so I cannot really generate the exact same coordinates. But what I can tell you is this happens for any number of any coordinates. – naman1901 Oct 22 '16 at 14:06
  • Could the issue have something to do with `x = 0; y = 0;` part? It seems that you very deliberately start with (0, 0). You'd probably want to start with `poly[0]` instead. – Igor Tandetnik Oct 22 '16 at 14:08
  • @IgorTandetnik The formula requires me to calculate a sum. So I would naturally initialize my variables with (0,0) and iteratively add the next term in the equation. – naman1901 Oct 22 '16 at 14:09
  • Open B-Splines have repeated values at the beginning and end of the knot vector to ensure interpolation of the first and last point (see the examples on [Wikipedia](https://en.wikipedia.org/wiki/B-spline)). Division by zero does not necessarily lead to an exception. It may lead as well to a nan. – Nico Schertler Oct 22 '16 at 14:10
  • @NicoSchertler Tried both your suggestions, doesn't help. Thanks though :) – naman1901 Oct 22 '16 at 14:18
  • @naman1901 - cheers. I'll play around with the centroids of the circles then. Though can't help but wonder why I haven't seen the cause of a blending towards 0 for the 'outtermost' half of the first/last segments. One more thing, does changing the value chosen for `d` - the degree of the curve make much difference in the wrongly blended areas? – enhzflep Oct 22 '16 at 14:22
  • @enhzflep Thanks for your time, but after investing too much time in this, I finally found the solution in a line in my textbook that I missed. – naman1901 Oct 22 '16 at 14:27
  • @enhzflep Also, to answer your question on the value of `d`, it didn't make much difference in the faulty code. The curves from the starting and end points always went to the origin. – naman1901 Oct 22 '16 at 14:32
  • 1
    @naman1901 - Fantastic! Not the time expended, of course - but the fact you were able to self-answer. One of the better forms of learning methinks, bravvo! – enhzflep Oct 22 '16 at 15:14

2 Answers2

2

So after investing way more time than I should have, I finally found the answer in a line in my textbook that I missed. Apparently, the curve is defined only for values of u between uVec[d-1] and uVec[n].

naman1901
  • 305
  • 4
  • 16
-1

So after investing way more time than I should have, I finally found the answer in a line in my textbook that I missed. Apparently, the curve is defined only for values of u between uVec[d-1] and uVec[n].

It means that mistake is in function "blend" Conditinon (uVec[k]<=u && u<uVec[k+1])