/* NURB curve (1-dimension) Testing whether we really get a quarter circle with the NURBS given in Rogers and also in Hill, and whether the curve goes outside the convex hull. Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include #include #include GLUnurbsObj *myNurb; int uOrder=3; const int numPoints = 3; GLfloat W = sqrt(2)/2; GLfloat points[numPoints][4]; GLfloat pointsWeights[numPoints][4] = { {1,0,0,1}, {1,1,0,W}, {0,1,0,1} }; // evaluate the ith b-spline function using Cox-de Boor recursion. // The index "k" is from 0 to L, where there are L control points; // that is, it chooses the control point that corresponds to this // basis spline. This code is Hill, page 631. bool trace = false; GLfloat bSpline(int k, int order, float t, float knots[]) { char* indent[4] = {""," "," "," "}; float term1=0, term2=0, denom1, denom2, bk, bk1; if(trace) printf("%s bSpline(%d,%d,%f)\n",indent[order],k,order,t); if(1==order) { float result = (t >= knots[k] && t < knots[k+1]); if(trace) printf("%s bSpline(%d,%d,%f)=>%f\n",indent[order], k,order,t,result); return result; } denom1 = knots[k+order-1] - knots[k]; if(denom1 == 0.0) { if(trace) printf("%s denom1 is zero\n",indent[order]); } else { bk=bSpline(k,order-1,t,knots); term1 = (t-knots[k])*bk/denom1; if(trace) printf("%s t-knots[k]=%f bk=%f denom1=%f term1=%f\n",indent[order], t-knots[k],bk,denom1,term1); } denom2 = knots[k+order] - knots[k+1]; if(denom2 == 0.0) { if(trace) printf("%s denom2 is zero\n",indent[order]); } else { float bk1=bSpline(k+1,order-1,t,knots); term2 = (knots[k+order]-t)*bk1/denom2; if(trace) printf("%s knots[k+order]-t=%f bk1=%f denom2=%f term2=%f\n",indent[order], knots[k+order]-t,bk1,denom2,term2); } if(trace) printf("%s bSpline(%d,%d,%f)=>%f\n",indent[order],k,order,t,term1+term2); return term1+term2; } // This is the rational version of the bSpline function for use with // non-homogenous coordinates. GLfloat nurbBasis(int k, int order, float t, int numPts, GLfloat weights[], GLfloat knots[]) { float denom = 0.0; for(int i=0; i 1) printf("coef = %f > 1 when k=%d\n",coef,cp); for(int i=0; i<3; i++) P[i] += coef*points[cp][i]; } if(sum > 1.01 || sum < 0.99) printf("sum isn't unity: %f\n",sum); } // eval a nurb curve using the homogeneous coordinate idea of Hill void nurbEval2(int order, float t, int numPts, GLfloat points[][4], GLfloat weights[], GLfloat knots[], GLfloat P[]) { P[0] = P[1] = P[2] = P[3] = 0; for(int cp=0; cp1.001 || c < 0.999 ) { printf("bSpline sum for t=%f is %f\n",i/10.0,c); trace=true; for(int j=0; j= '0' && k <= '9') tmp = tmp*10 + k-'0'; if(k == '\r') { whatToDisplay=tmp; tmp=0; printf("what to display = %d\n",whatToDisplay); glutPostRedisplay(); } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(650, 650); glutCreateWindow("NURBS!"); glutDisplayFunc(display); glutKeyboardFunc(keys); myNurb=gluNewNurbsRenderer(); gluNurbsProperty(myNurb,GLU_DISPLAY_MODE,GLU_FILL); glEnable(GL_MAP1_VERTEX_4); glutMainLoop(); return 0; }