#include "point3D.h" #define M_PI 3.14159265358979323846 const GLshort N_ctr = 14; //Размерность матрицы контрольных точек const GLshort M_ctr = 14; //Размеры области const GLdouble Xmin = 0; const GLdouble Xmax = 3 * M_PI; const GLdouble Ymin = 0; const GLdouble Ymax = 3 * M_PI; const GLdouble Z = 1.5; const GLdouble Xmid = Xmin + (Xmax - Xmin) / 2.0; const GLdouble Ymid = Ymin + (Ymax - Ymin) / 2.0; const GLdouble XMAX = sqrt(Xmid*Xmid + Ymid*Ymid); const GLdouble DX = XMAX - Xmid + 1; const GLshort N = 27; //Размерность матрицы точек сплайна const GLshort M = 27; extern GLint winWidth; // Исходный размер окна на экране. extern GLint winHeight; extern Matrix4fT Transform; extern Point2fT MousePt; extern ArcBallT ArcBall; bool isMovePoint; bool isZoom; extern bool isClicked; extern bool isRClicked; double xTransZoom; double yTransZoom; double zTransZoom; float ZoomCoeff; bool drawLineSegments; bool drawLineSplines; point3D PtCtr[N_ctr][M_ctr]; point3D Pt[N][M]; short i, j; short iMove, jMove; void GenerateControlPoints(bool isCalcXYZ) { if (isCalcXYZ) { for (i = 0; i < N_ctr; i++) for (j = 0; j < M_ctr; j++) { PtCtr[i][j].x = Xmin + i * (Xmax - Xmin) / (N_ctr - 1) - Xmid; PtCtr[i][j].y = Ymin + j * (Ymax - Ymin) / (M_ctr - 1) - Ymid; PtCtr[i][j].z = Z * sin(PtCtr[i][j].x) * sin(PtCtr[i][j].y); } } // ДОБАВИТЬ ИНИЦИАЛИЗАЦИЮ ПАРАМЕТРИЧЕСКИХ КООРДИНАТ t и tau //for (i = 0; i < N_ctrl; i++) //{ // for (j = 0; j < M_ctrl; j++) // { // PtCtr[i][j].t = t; // PtCtr[i][j].tau = tau; // } //} } void calculateLineSurfaceSplines() { //// ДОБАВИТЬ КОД РАСЧЕТА ТОЧЕК ЛИНЕЙНОГО ПОВЕРХНОСТНОГО СПЛАЙНА //for (i = 0; i < N; i++) //{ // for (j = 0; j < M; j++) // { // Pt[i][j].x =; // Pt[i][j].y =; // Pt[i][j].z =; // } //} } void init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); // Цвет окна выбран белым. glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glOrtho(Xmin - Xmid - DX, Xmax - Xmid + DX, Ymin - Ymid - DX, Ymax - Ymid + DX, -(Xmax - Xmid + DX), Xmax - Xmid + DX); drawLineSegments = true; drawLineSplines = false; isMovePoint = false; isZoom = false; xTransZoom = 0.0; yTransZoom = 0.0; zTransZoom = 0.0; ZoomCoeff = 1.0; GenerateControlPoints(true); } void plotLineSegments() { glColor3f(0.0, 1.0, 0.0); // Цвет рисования выбран зеленым for (i = 0; i < N_ctr; i++) { glBegin(GL_LINE_STRIP); for (j = 0; j < M_ctr; j++) { glVertex3f(PtCtr[i][j].x, PtCtr[i][j].y, PtCtr[i][j].z); } glEnd(); } glColor3f(0.0, 0.0, 1.0); // Цвет рисования выбран синим for (j = 0; j < M_ctr; j++) { glBegin(GL_LINE_STRIP); for (i = 0; i < N_ctr; i++) { glVertex3f(PtCtr[i][j].x, PtCtr[i][j].y, PtCtr[i][j].z); } glEnd(); } } void displayFnc(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.0, 0.0, 0.0); // Цвет рисования выбран черным glPointSize(10.0); glPushMatrix(); glMultMatrixf(Transform.M); glScalef(ZoomCoeff, ZoomCoeff, ZoomCoeff); for (i = 0; i < N_ctr; i++) for (j = 0; j < M_ctr; j++) PtCtr[i][j].Draw(); if (drawLineSplines) { glColor3f(1.0, 0.0, 0.0); // Цвет рисования выбран красным glPointSize(7.0); for (i = 0; i < N; i++) for (j = 0; j < M; j++) Pt[i][j].Draw(); } if (drawLineSegments) plotLineSegments(); glPopMatrix(); glFlush(); } void winReshapeFnc(GLint newWidth, GLint newHeight) { // Обновление параметров размера окна. winWidth = newWidth; winHeight = newHeight; // Обновление точки обзора и проекционных параметров. glViewport(0, 0, newWidth, newHeight); ArcBall.ArcBall_t_Set(newWidth, newHeight); } void plotMode(GLint selectedOption) { switch (selectedOption) { case 1: drawLineSplines = !drawLineSplines; if (drawLineSplines) calculateLineSurfaceSplines(); break; case 2: drawLineSegments = !drawLineSegments; break; } glutPostRedisplay(); } void MouseBtCl(GLint button, GLint action, GLint xMouse, GLint yMouse) { switch (button) { case GLUT_LEFT_BUTTON: switch (action) { case GLUT_DOWN: isMovePoint = false; for (i = 0; i < N_ctr; i++) for (j = 0; j < M_ctr; j++) { if (PtCtr[i][j].select == true) { isMovePoint = true; iMove = i; jMove = j; } } if (!isMovePoint) { MousePt.s.X = (GLfloat)xMouse; MousePt.s.Y = (GLfloat)yMouse; isClicked = true; } break; case GLUT_UP: isClicked = false; break; } break; case GLUT_MIDDLE_BUTTON: switch (action) { case GLUT_DOWN: isRClicked = true; break; case GLUT_UP: isRClicked = false; break; } break; } Update(); glutPostRedisplay(); } void MouseBtMove(GLint xMouse, GLint yMouse) { if (isMovePoint) { gluUnProject(xMouse, PtCtr[iMove][jMove].viewport.T[3] - (GLint)yMouse - 1, PtCtr[iMove][jMove].winz, PtCtr[iMove][jMove].modelMatrix.M, PtCtr[iMove][jMove].projMatrix.M, PtCtr[iMove][jMove].viewport.T, &PtCtr[iMove][jMove].x, &PtCtr[iMove][jMove].y, &PtCtr[iMove][jMove].z); GenerateControlPoints(false); calculateLineSurfaceSplines(); } MousePt.s.X = (GLfloat)xMouse; MousePt.s.Y = (GLfloat)yMouse; Update(); glutPostRedisplay(); } void MouseMove(GLint xMouse, GLint yMouse) { for (i = 0; i < N_ctr; i++) for (j = 0; j < M_ctr; j++) { PtCtr[i][j].select = false; if (PtCtr[i][j].PtInRect(xMouse, yMouse)) PtCtr[i][j].select = true; } glutPostRedisplay(); } void ZoomOn(GLubyte key, GLint xMouse, GLint yMouse) { switch (key) { case 'a': isZoom = true; ZoomCoeff += 0.1; break; case 'z': isZoom = true; ZoomCoeff -= 0.1; break; default: break; } glutPostRedisplay(); } void ZoomOff(GLubyte key, GLint xMouse, GLint yMouse) { switch (key) { case 'a': isZoom = false; break; case 'z': isZoom = false; break; default: break; } } void main(int argc, char** argv) { glutInit(&argc, argv); // Инициализация GLUT glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // Установка режима дисплея glutInitWindowPosition(0, 0); // Задает верхнее левое положение окна изображения. glutInitWindowSize(winWidth, winHeight); glutCreateWindow("Лабораторная работа № 2"); //Создает окно изображения init(); // Процедура инициализации. glutDisplayFunc(displayFnc); glutCreateMenu(plotMode); glutAddMenuEntry("Линейный поверхностный сплайн", 1); glutAddMenuEntry("Соединение ломанными", 2); glutAttachMenu(GLUT_RIGHT_BUTTON); // ВЫбор опции меню с использованием правой кнопки мыши. glutReshapeFunc(winReshapeFnc); glutMouseFunc(MouseBtCl); glutMotionFunc(MouseBtMove); glutPassiveMotionFunc(MouseMove); glutKeyboardFunc(ZoomOn); glutKeyboardUpFunc(ZoomOff); glutMainLoop(); }