Jump to content
  • Advertisement
Sign in to follow this  
Specialist

NURBS bias function undefined

This topic is 4922 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 < t && t < k[i+1] ? 1 : 0;
	
	cout << (t-k) << " / " << (k[i+d-1]-k) << " * bias + ";
	cout << (k[i+d]-t) << " / " << (k[i+d]-k[i+1]) << " * bias" << endl;

	return (t-k)/(k[i+d-1]-k)*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) 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
Advertisement
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 && u <= knots[i+1]) return 1.0;
else return 0.0;
}

denom = knots[i+deg]-knots;
if(denom==0.0) ft = 0.0;
else ft = ((u-knots)/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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!