#include "buttons.h" #include "windows.h" #include "plot.h" /************************************************************/ /* CURVES. */ /************************************************************/ /****************************************/ /* Control points. */ /****************************************/ void CURVE_CONTROL_POINTS(void) { int i; glPointSize(4); glColor3f(1.0, 0.0, 1.0); glBegin(GL_POINTS); for (i = 0; i <= nocPoints; i++) { glVertex3fv(&cPoints[i][0]); } glEnd(); glPointSize(1); } /****************************************/ /* Bezier. */ /****************************************/ void BEZIER_CURVE(void) { int i; glColor3f(1.0, 0.0, 0.0); glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, nocPoints-1, &cPoints[0][0]); glEnable(GL_MAP1_VERTEX_3); glBegin(GL_LINE_STRIP); for (i = 0; i <= 100; i++) { glEvalCoord1f((GLfloat)i/100.0); } glEnd(); } /****************************************/ /* Cubic bSpline. */ /****************************************/ void BUILDKNOTS(int m ,int L, double knot[]) { int i; if (L < (m-1)) return; for (i = 0; i <= L+m; i++) { if (i < m) knot[i] = 0.0; else if (i <= L) knot[i] = i - m + 1; else knot[i] = L - m + 2; } } double BSPLINE(int k, int m, double t, double knot[]) { double denom1, denom2; double sum = 0.0; if (m == 1) return (t >= knot[k] && t < knot[k+1]); denom1 = knot[k+m-1] - knot[k]; if (denom1 != 0.0) { sum = (t - knot[k]) * BSPLINE(k, m-1, t, knot) / denom1; } denom2 = knot[k+m] - knot[k+1]; if (denom2 != 0.0) { sum += (knot[k+m] - t) * BSPLINE(k+1, m-1, t, knot) / denom2; } return sum; } void BSPLINE_CURVE(int m) { int x, stop; int k; int L = nocPoints; //m+1; double xx; double sumX, sumY; double knot[200] ; if (m == 1) { m = nocPoints; stop = (10 * (nocPoints-3)); } else { stop = (10 * (nocPoints-2)); } BUILDKNOTS(m, L, knot); glColor3f(0.0, 0.25*m, 0.0); glBegin(GL_LINE_STRIP); for (x = 0; x < stop; x++) { xx = (double)x / 10.0; sumX = 0.0; sumY = 0.0; for (k = 0; k <= L; k++) { sumX += cPoints[k][0] * BSPLINE(k, m, xx, knot); sumY += cPoints[k][1] * BSPLINE(k, m, xx, knot); } glVertex3f(sumX, sumY, 0.0); } glEnd(); } /****************************************/ /* Displays curves in TARGET window. */ /****************************************/ void CURVE_DISPLAY(void) { glLoadIdentity(); glDrawBuffer(GL_BACK); glTranslated(150, 150, 0); glScaled(50, 50, 50); if (flag == 1) BSPLINE_CURVE(1); // if (flag == 1) BEZIER_CURVE(); if (flag == 2) BSPLINE_CURVE(2); if (flag == 3) BSPLINE_CURVE(3); if (flag == 4) BSPLINE_CURVE(4); CURVE_CONTROL_POINTS(); glutSwapBuffers(); glLoadIdentity(); } /************************************************************/ /* SURFACES. */ /************************************************************/ /****************************************/ /* Control points. */ /****************************************/ void SURFACE_CONTROL_POINTS(void) { int i, j; glPointSize(4); glColor3f(1.0, 0.0, 1.0); for (i = 0; i < 4; i++) { glBegin(GL_LINE_STRIP); for (j = 0; j < 4; j++) { glVertex3fv(&sPoints[i][j][0]); } glEnd(); glBegin(GL_POINTS); for (j = 0; j < 4; j++) { glVertex3fv(&sPoints[i][j][0]); } glEnd(); } glPointSize(1); } /****************************************/ /* Cubic bSpline. */ /****************************************/ void BSPLINE_SURFACE(int m) { int x, i, stop; int k; int L = nosPoints; //m+1; double xx; double sumX, sumY; double knot[200] ; GLfloat points[6][3]; if (m == 1) { m = nosPoints; stop = (10 * (nosPoints-3)); } else { stop = (10 * (nosPoints-2)); } BUILDKNOTS(m, L, knot); glColor3f(0.0, 0.25*m, 0.0); for (i = 0; i <= nosPoints; i++) { points[i][0] = sPoints[0][i][0]; points[i][1] = sPoints[0][i][1]; } glBegin(GL_LINE_STRIP); for (x = 0; x < stop; x++) { xx = (double)x / 10.0; sumX = 0.0; sumY = 0.0; for (k = 0; k <= L; k++) { sumX += points[k][0] * BSPLINE(k, m, xx, knot); sumY += points[k][1] * BSPLINE(k, m, xx, knot); } glVertex3f(sumX, sumY, sPoints[0][0][2]); } glEnd(); for (i = 0; i < nosPoints; i++) { points[i][0] = sPoints[3][i][0]; points[i][1] = sPoints[3][i][1]; } glBegin(GL_LINE_STRIP); for (x = 0; x < stop; x++) { xx = (double)x / 10.0; sumX = 0.0; sumY = 0.0; for (k = 0; k <= L; k++) { sumX += points[k][0] * BSPLINE(k, m, xx, knot); sumY += points[k][1] * BSPLINE(k, m, xx, knot); } glVertex3f(sumX, sumY, sPoints[3][0][2]); } glEnd(); for (i = 0; i <= nosPoints; i++) { points[i][0] = sPoints[i][0][2]; points[i][1] = sPoints[i][0][1]; } glBegin(GL_LINE_STRIP); for (x = 0; x < stop; x++) { xx = (double)x / 10.0; sumX = 0.0; sumY = 0.0; for (k = 0; k <= L; k++) { sumX += points[k][0] * BSPLINE(k, m, xx, knot); sumY += points[k][1] * BSPLINE(k, m, xx, knot); } glVertex3f(sPoints[0][0][0], sumY, sumX); } glEnd(); for (i = 0; i < nosPoints; i++) { points[i][0] = sPoints[i][3][2]; points[i][1] = sPoints[i][3][1]; } glBegin(GL_LINE_STRIP); for (x = 0; x < stop; x++) { xx = (double)x / 10.0; sumX = 0.0; sumY = 0.0; for (k = 0; k <= L; k++) { sumX += points[k][0] * BSPLINE(k, m, xx, knot); sumY += points[k][1] * BSPLINE(k, m, xx, knot); } glVertex3f(sPoints[0][3][0], sumY, sumX); } glEnd(); } /* void BSPLINE_SURFACE(int m) { int x, y, stop; int i, k; int L = nosPoints; //m+1; int M = nosPoints; double xx, yy; double sumX, sumY, sumZ; double knot[200] ; if (m == 1) { m = nosPoints; stop = (40 * (nosPoints-3)); } else { stop = (40 * (nosPoints-2)); } BUILDKNOTS(m, L, knot); glColor3f(0.0, 0.25*m, 0.0); for (x = 0; x < stop; x++) { xx = (GLfloat)x / 10.0; glBegin(GL_LINE_STRIP); for (y = 0; y < stop; y++) { yy = (GLfloat)y / 10.0; sumX = 0.0; sumY = 0.0; sumZ = 0.0; for (k = 0; k <= L; k++) { for (i = 0; i <= M; i++) { sumX += sPoints[k][i][0] * BSPLINE(k, m, xx, knot) * BSPLINE(i, m, yy, knot); sumY += sPoints[k][i][1] * BSPLINE(k, m, xx, knot) * BSPLINE(i, m, yy, knot); sumZ += sPoints[k][i][2] * BSPLINE(k, m, xx, knot) * BSPLINE(i, m, yy, knot); } } glVertex3f(sumX, sumY, sumZ); } glEnd(); } } */ /****************************************/ /* Displays surfaces in TARGET window. */ /****************************************/ void SURFACE_DISPLAY(void) { glLoadIdentity(); glDrawBuffer(GL_BACK); glTranslated(200, 100, 0); glScaled(50, 50, 50); glRotatef(R, 0.0, 0.0, 1.0); glRotatef(Y, 1.0, 0.0, 0.0); glRotatef(P, 0.0, 1.0, 0.0); if (flag == 1) BSPLINE_SURFACE(1); if (flag == 2) BSPLINE_SURFACE(2); if (flag == 3) BSPLINE_SURFACE(3); if (flag == 4) BSPLINE_SURFACE(4); SURFACE_CONTROL_POINTS(); glutSwapBuffers(); glLoadIdentity(); } /************************************************************/ /* GUI. */ /************************************************************/ /****************************************/ /* Main window display. */ /****************************************/ void MAIN_WINDOW(void) { glDrawBuffer(GL_BACK); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(0.6, 0.6, 0.6); glBegin(GL_QUADS); glVertex2i( 0, 0); glVertex2i(winWidth, 0); glVertex2i(winWidth, winHeight); glVertex2i( 0, winHeight); glEnd(); BEZR_BUTTON.DRAW(); SPL2_BUTTON.DRAW(); SPL3_BUTTON.DRAW(); SPL4_BUTTON.DRAW(); Bezr_BUTTON.DRAW(); Spl2_BUTTON.DRAW(); Spl3_BUTTON.DRAW(); Spl4_BUTTON.DRAW(); CLR__BUTTON.DRAW(); EXIT_BUTTON.DRAW_HILITE(0.7, 0.0, 0.0); TARGET_WINDOW.DRAW(); TARGET_WINDOW.CLEAR(); glutSwapBuffers(); } /************************************************************/ /* CALLBACK FUNTIONS. */ /************************************************************/ /****************************************/ /* Mouse control. */ /****************************************/ void myMouse(int button, int state, int x, int y) { y = (winHeight - y); if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { glFinish(); if (BEZR_BUTTON.SELECTED(x, y)) { BEZR_BUTTON.CLICK(); flag = 1; CURVE_DISPLAY(); } if (SPL2_BUTTON.SELECTED(x, y)) { SPL2_BUTTON.CLICK(); flag = 2; CURVE_DISPLAY(); } if (SPL3_BUTTON.SELECTED(x, y)) { SPL3_BUTTON.CLICK(); flag = 3; CURVE_DISPLAY(); } if (SPL4_BUTTON.SELECTED(x, y)) { SPL4_BUTTON.CLICK(); flag = 4; CURVE_DISPLAY(); } if (Bezr_BUTTON.SELECTED(x, y)) { Bezr_BUTTON.CLICK(); flag = 1; SURFACE_DISPLAY(); } if (Spl2_BUTTON.SELECTED(x, y)) { Spl2_BUTTON.CLICK(); flag = 2; SURFACE_DISPLAY(); } if (Spl3_BUTTON.SELECTED(x, y)) { Spl3_BUTTON.CLICK(); flag = 3; SURFACE_DISPLAY(); } if (Spl4_BUTTON.SELECTED(x, y)) { Spl4_BUTTON.CLICK(); flag = 4; SURFACE_DISPLAY(); } if (CLR__BUTTON.SELECTED(x, y)) { CLR__BUTTON.CLICK(); TARGET_WINDOW.CLEAR(); } if (EXIT_BUTTON.SELECTED(x, y)) { EXIT_BUTTON.CLICK(); glutDestroyWindow(window); exit(0); } } } /****************************************/ /* Resizes screen (if required) */ /****************************************/ void myResize(int width, int height) { glutReshapeWindow(winWidth, winHeight); } /****************************************/ /* Redisplays screen (if required) */ /****************************************/ void myDisplay(void) { drawFlag = glutLayerGet(GLUT_NORMAL_DAMAGED); if (drawFlag == 1) { MAIN_WINDOW(); drawFlag = 0; } else { glutSwapBuffers(); } } /****************************************/ /* Initializes OPENGL parameters */ /****************************************/ void myInit(void) { glPointSize(1); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glOrtho(0.0, (GLdouble)winWidth, 0.0, (GLdouble)winHeight, -1000.0, 1000.0); glMatrixMode(GL_MODELVIEW); glEnable(GL_NORMALIZE); glLoadIdentity(); } /************************************************************/ /* MAIN. */ /************************************************************/ int main(int argc, char **argv) { glutInit(&argc, argv) ; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowSize(winWidth, winHeight); glutInitWindowPosition(winX, winY); window = glutCreateWindow("NURBS by R. Marsh."); glutDisplayFunc(myDisplay); glutReshapeFunc(myResize); glutMouseFunc(myMouse); myInit(); glutMainLoop(); return 1; }