#include #include #ifdef __APPLE__ #include #else #include #endif GLint mouse_button = -1; GLint mouse_state = -1; void Find_Nearest(int, int); int ni, nj; int width; GLdouble wx[4], wy[4], wz[4]; int SELECTED = GL_FALSE; GLfloat CtrlPoints[4][2] = { {200., 200.}, {200., 300.}, {300., 300.}, {300., 200.}}; GLfloat BezMatrix[4][4] = { { -1.0, 3.0, -3.0, 1.0}, { 3.0, -6.0, 3.0, 0.0}, { -3.0, 3.0, 0.0, 0.0}, { 1.0, 0.0, 0.0, 0.0}}; GLfloat BP[4][2]; int in_box = -1; int off_x, off_y; void init() { int i, j, k; for(i=0; i<4; i++) for(j=0; j<2; j++) { BP[i][j] = 0.0; for(k=0; k < 4; k++) { BP[i][j] += BezMatrix[i][k] * CtrlPoints[k][j]; } } } void draw_Ctrl_Points() { int i; glColor3f(1.0, 1.0, 1.0); glBegin(GL_POINTS); glPointSize(4.0); for(i=0; i<4; i++) glVertex2f(CtrlPoints[i][0], CtrlPoints[i][1]); glEnd(); glBegin(GL_LINE_STRIP); for(i=0; i<4; i++) glVertex2f(CtrlPoints[i][0], CtrlPoints[i][1]); glEnd(); for(i=0; i<4; i++) { glBegin(GL_LINE_LOOP); if(i== in_box) glColor3f(0.0, 1.0, 1.0); else glColor3f(1.0, 0.0, 0.0); glVertex2f(CtrlPoints[i][0] -5., CtrlPoints[i][1] - 5.); glVertex2f(CtrlPoints[i][0] -5., CtrlPoints[i][1] + 5); glVertex2f(CtrlPoints[i][0] + 5., CtrlPoints[i][1] + 5.); glVertex2f(CtrlPoints[i][0] +5. , CtrlPoints[i][1] -5.); glEnd(); } // draw the highlighted one if(SELECTED) { glPointSize(5.0); glColor3f(1, 0, 0); glBegin(GL_POINTS); glVertex2f(CtrlPoints[in_box][0], CtrlPoints[ni][1]); glEnd(); } } void draw_curve() { float u; float xx, yy; GLfloat uu[4]; int i, j; u = 0.0; glBegin(GL_POINTS); glPointSize(2.0); glColor3f(1.0, 1.0, 0.0); for(u=0.0; u<=1.0; u+=0.01) { uu[3] = 1.; uu[2] = u; uu[1] = uu[2]*u; uu[0] = uu[1]*u; xx = 0; for(i=0; i < 4; i++) xx += uu[i] * BP[i][0]; yy = 0; for(i=0; i < 4; i++) yy += uu[i] * BP[i][1]; glVertex2f(xx, yy); } glEnd(); } void display(void) { glClear (GL_COLOR_BUFFER_BIT); draw_Ctrl_Points(); draw_curve(); glFlush(); } void reshape(int w, int h) { width=w; glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 500.0, 500.0, 0.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static m_off_x, m_off_y; void move_ctrlpoint(int button, int x, int y) { int i; //m_off_x = x - (int)(CtrlPoints[i][0]); //m_off_y = y - (int)(CtrlPoints[i][1]); printf("off_x=%d, off_y=%d\n", off_x, off_y); switch (button) { case GLUT_LEFT_BUTTON: if(in_box != -1) { CtrlPoints[in_box][0] = (float)(x-off_x); CtrlPoints[in_box][1] = (float)(y-off_y); init(); }; default: break; } } void mouse(int button, int state, int x, int y) { int i; mouse_state = state; mouse_button = button; //move_ctrlpoint(button, x, y); switch (button) { case GLUT_LEFT_BUTTON: if (mouse_state == GLUT_UP) { if(in_box != -1) { CtrlPoints[in_box][0] = (float)(x-off_x); CtrlPoints[in_box][1] = (float)(y-off_y); init(); } in_box = -1; } if (mouse_state == GLUT_DOWN) { printf("x=%d, y=%d\n", x, y); in_box = -1; for(i=0; i<4; i++) { if( (x > (int)(CtrlPoints[i][0] - 15.)) && (y > (int)(CtrlPoints[i][1] - 15.)) && (x < (int)(CtrlPoints[i][0] + 15.)) && (y < (int)(CtrlPoints[i][1] + 15.))) { in_box = i; off_x = x - (int)(CtrlPoints[i][0]); off_y = y - (int)(CtrlPoints[i][1]); printf("inside_box %d!\n", in_box); printf("%d %d %d %d \n", (int)(CtrlPoints[i][0] -5.), (int)(CtrlPoints[i][1] - 5.), (int)(CtrlPoints[i][0] + 5.), (int)(CtrlPoints[i][1] + 5.)); break; } } } break; default: break; } /* */ glFlush(); display(); } void Find_Nearest(int x, int y) { int i, j; GLint viewport[4]; GLdouble mvmatrix[16], projmatrix[16]; GLdouble td, dd; glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); for(i=0; i<4; i++) { gluProject((GLdouble)CtrlPoints[i][0], (GLdouble)CtrlPoints[i][1], 0, mvmatrix, projmatrix, viewport, &(wx[i]), &(wy[i]), &(wz[i])); wy[i]=(GLdouble)width-wy[i]; printf("wx=%lf, wy=%lf, wz%lf\n", wx[i], wy[i], wz[i]); }; printf("\n"); printf("x=%d, y=%d\n", x, y); dd=9e+9; ni=0; for(i=0; i<4; i++) { td=((GLdouble)x -wx[i]) * ((GLdouble)x-wx[i]) + ((GLdouble)y -wy[i]) * ((GLdouble)y-wy[i]); if(td