/* NURB curve (2-dimension) Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include #include #include "tw.h" #include //mouse mode int mouseMode = 1; int drawMode = 0; //wireframe int curveMode = 0; //show curve //for picking int count; int p; //number of points the user wants GLint uPointsCount=11; GLint vPointsCount = 9; GLUnurbsObj *myNurb; GLint uOrder=4; //degree+1 GLint vOrder = 3; GLint uKnotCount; GLint vKnotCount = 12; GLfloat vKnot[12] = {0,0,0,1,1,2,2,3,3,4,4,4}; GLuint material = 0; GLuint textureIDs[3]; /*------------------------------------------------------------------- CONTROL POINTS One can construct an object out of a polynomial (you have to supply many more points, though!). Specifying control points is much more efficient for the programmer.*/ GLfloat points[13][9][4]; GLfloat conicPoints[9][4]; /*GLfloat vasePoints[6][4] = { //lamp {-14,-11.8,0,1}, {-11.9,-2.9,0,1},{-3.4,4.5,0,1},{-3.3,7.3,0,1}, {-3.3,8.5,0,1},{0,8.5,0}, };*/ /*GLfloat vasePoints[5][4] = { //hershey's kiss {0,-10.5,0,1}, {-13.7,-10.6,0,1},{-8.0,-4.6,0,1}, {-3.0,1.1,0,1}, {0,4.7,0,1}};*/ GLfloat vasePoints[13][4] = { //vase's profile (u) {-3.9,-14.0,0,1}, {-3.9,-14.0,0,1}, {-3.9,-14.0,0,1}, {-5,-10,0,1}, {-12.5,-5.0,0,1}, {-12.5,-5.0,0,1}, {-12.5,-5.0,0,1}, {-10,3.0,0,1}, {0,2.6,0,1}, {0,2.6,0,1},{0,2.6,0,1},{2.2,2.4,0,1},{0,0,0,1}, }; /*GLfloat vasePoints[3][4] = { {-3,4,0,1}, {-3,0,0,1}, {-3,-4,0,1} };*/ GLfloat initConicPoints(GLfloat x, GLfloat y) { int i,j; // GLfloat conicPointsWeights[7][4]= { /* {0,y,x*-0.5,1}, {x*0.5,y,x*-0.5,0.5}, {x*0.25,y,x*-0.0669873,1}, {0,y,x*0.3880254,0.5}, {x*-0.25,y,x*-0.0669873,1}, {x*-0.5,y,x*-0.5,0.5}, {0,y,x*-0.5,1}, };*/ GLfloat a = sqrt(2)/2; GLfloat conicPointsWeights[9][4]= { {x,y,0,1},{x,y,x,a},{0,y,x,1},{-x,y,x,a}, {-x,y,0,1},{-x,y,-x,a}, {0,y,-x,1},{x,y,-x,a},{x,y,0,1}}; for(i = 0; i < 9; i++) { conicPoints[i][3] = conicPointsWeights[i][3]; for(j = 0; j<3; j++) { conicPoints[i][j] = conicPointsWeights[i][j]*conicPoints[i][3]; } } } void initSurface() { int u,v; for(u=0;u< uPointsCount; u++) {//u<2; u++) { initConicPoints(vasePoints[u][0],vasePoints[u][1]); // is the following still necessary? -- sda for(v=0; vscreen[0]-4 && yscreen[1]-4) return i; } return 15; } void pick(int x, int y, int element) { if(p<15) { twTriple world; //new coords for element twTriple A,B,V; twTriple winA = {x,y,0}; twTriple winB = {x,y,1}; twUnProject(A,winA); twUnProject(B,winB); twVector(V,B,A); twPointOnLine(vasePoints[element],A,V,0.5); } } static int mouse_x, mouse_y; void myMouse(int button, int state, int x, int y) { if (mouseMode == 0) twMouseFunction(button,state, x,y); else { y=650-y; if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN){ mouse_x=x; mouse_y=y; p = testClick(x,y); } } } void myMotion(int x, int y) { if(mouseMode == 0) twMotionFunction(x,y); else { y=650-y; pick(x,y,p); initSurface(); glutPostRedisplay(); } } void printCoords(unsigned char key, int x, int y) { int i; printf("Your current control points are: \n"); for(i=0; i