Sign in to follow this  

NURBS bias function undefined

This topic is 4731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to implement a NURBS class for my game and I can't seem to get the bias function to compute properly. It keeps running into a division by zero error.
class SomeNurbClass
{
	float * k; // knot define somewhere
	...
};

...
float SomeNurbClass::bias(int i, int d, float t)
{// i = sigma index, d = degree, t = time
	if (d == 0)
		return k[i] < t && t < k[i+1] ? 1 : 0;
	
	cout << (t-k[i]) << " / " << (k[i+d-1]-k[i]) << " * bias + ";
	cout << (k[i+d]-t) << " / " << (k[i+d]-k[i+1]) << " * bias" << endl;

	return (t-k[i])/(k[i+d-1]-k[i])*bias(i, d-1, t) +
		(k[i+d]-t)/(k[i+d]-k[i+1])*bias(i+1, d-1, t);
}
Just by looking at this section in the denomintor (k[i+d-1]-k[i]) if those two values in the knot vector are equal it's an error. Is there some restriction I'm missing? btw I'm using control points {x, y, z, w} = {{1,1,1,1},{5,5,5,1},{-5,-5,-5,1},{1,1,1,1}} and knot vector = {0,1,2,3,4,5}. 4 control point and order of 2 -> degree 3. output w/ couts: 0 / 2 * bias + 3 / 2 * bias 0 / 1 * bias + 2 / 1 * bias 0 / 0 * bias + 1 / 0 * bias -1 / 0 * bias + 2 / 0 * bias -1 / 1 * bias + 3 / 1 * bias -1 / 0 * bias + 2 / 0 * bias -2 / 0 * bias + 3 / 0 * bias

Share this post


Link to post
Share on other sites
Hi. Here's my basis function for a NURBS curve. I've used it many projects, so hopefully it works well. The "u" argument is the parameter variable, i.e what you call "time" I guess. Hope it helps.


float NURBS::Basis(int i, int deg, float u, const vector<float> &knots) {

/* First term, Second term, Denominator */
float ft,st,denom = 0.0;

if(deg==0) {
if(u >= knots[i] && u <= knots[i+1]) return 1.0;
else return 0.0;
}

denom = knots[i+deg]-knots[i];
if(denom==0.0) ft = 0.0;
else ft = ((u-knots[i])/denom) * Basis(i,deg-1,u,knots);

denom = knots[i+deg+1]-knots[i+1];
if(denom==0.0) st = 0.0;
else st = ((knots[i+deg+1]-u)/denom) * Basis(i+1,deg-1,u,knots);

return (ft + st);
}

Share this post


Link to post
Share on other sites
Sorry I still can't get it to work. I've tried setting the result to zero when there is a division zero but it's giving a constant value for the output using the basis function you posted.

float control[number][4]; // {x,y,z,w};
...
void NURBS::evulate(Vector &v, const float time)
{
float n[3] = {0.0, 0.0, 0.0};
float c, d;
c = d = 0.0;
for (int k = 0; k < number; k++)
{
c = control[k][3] * basis(k, degree, time);
n[0] += c*control[k][0];
n[1] += c*control[k][1];
n[2] += c*control[k][2];
d += c;
}
v[0] = (d == 0) ? 0.0 : n[0] / d;
v[1] = (d == 0) ? 0.0 : n[1] / d;
v[2] = (d == 0) ? 0.0 : n[2] / d;
}


I tested the time from 0 to 1 incrementing by 1/4 and get these results which isn't right.

// input
control points = {{1,0,0,1},{2,3,0,1},{3,8,0,1},{4,16,0,1}}
knots = {0,1,2,3,4,5}

// output
time
0 [ x: 0 y: 0 z: 0 ]
0.25 [ x: 1 y: 0 z: 0 ]
0.5 [ x: 1 y: 0 z: 0 ]
0.75 [ x: 1 y: 0 z: 0 ]
1 [ x: 1 y: 0 z: 0 ]

Share this post


Link to post
Share on other sites

This topic is 4731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this