Загрузка данных


#include <GL/glut.h>
#pragma comment(lib, "freeglut.lib")
#include <stdlib.h>
#include <GL/glut.h>
#include <cmath>
#include <cstdio>


// ==================== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ====================

// Массив вершин куба (координаты от -1 до 1)
GLfloat vertices[8][3] = {
    {-1.0, -1.0, -1.0}, // 0 - передняя нижняя левая
    { 1.0, -1.0, -1.0}, // 1 - передняя нижняя правая
    { 1.0,  1.0, -1.0}, // 2 - передняя верхняя правая
    {-1.0,  1.0, -1.0}, // 3 - передняя верхняя левая
    {-1.0, -1.0,  1.0}, // 4 - задняя нижняя левая
    { 1.0, -1.0,  1.0}, // 5 - задняя нижняя правая
    { 1.0,  1.0,  1.0}, // 6 - задняя верхняя правая
    {-1.0,  1.0,  1.0}  // 7 - задняя верхняя левая
};

// Цвета для шести граней (без интерполяции - каждая грань одним цветом)
GLfloat faceColors[6][3] = {
    {1.0, 0.0, 0.0}, // 0 - красный (передняя грань, z = -1)
    {0.0, 1.0, 0.0}, // 1 - зеленый (правая грань, x = 1)
    {0.0, 0.0, 1.0}, // 2 - синий (задняя грань, z = 1)
    {1.0, 1.0, 0.0}, // 3 - желтый (левая грань, x = -1)
    {1.0, 0.0, 1.0}, // 4 - пурпурный (верхняя грань, y = 1)
    {0.0, 1.0, 1.0}  // 5 - голубой (нижняя грань, y = -1)
};

// Параметры камеры для перспективной проекции (нижний правый угол)
float eyeX = 5.0, eyeY = 5.0, eyeZ = 5.0;
float centerX = 0.0, centerY = 0.0, centerZ = 0.0;
float upX = 0.0, upY = 1.0, upZ = 0.0;

// Размеры окна
int windowWidth = 800;
int windowHeight = 800;

// ==================== УГЛЫ ДЛЯ ПРОЕКЦИЙ ====================

// ИЗОМЕТРИЧЕСКАЯ ПРОЕКЦИЯ
// fz = 0.8165 (√(2/3))
const float ISO_THETA = 35.264f;   // Поворот вокруг оси X (градусы)
const float ISO_PHI = 45.0f;       // Поворот вокруг оси Y (градусы)

// ДИМЕТРИЧЕСКАЯ ПРОЕКЦИЯ (по вашим расчётам)
// fz = 3/8 = 0.375
const float DIM_THETA = 15.4f;     // Поворот вокруг оси X (градусы)
const float DIM_PHI = 16.0f;       // Поворот вокруг оси Y (градусы)

// ==================== ФУНКЦИИ РИСОВАНИЯ ====================

void drawFace(int a, int b, int c, int d, float r, float g, float bl) {
    glColor3f(r, g, bl);
    glBegin(GL_POLYGON);
    glVertex3fv(vertices[a]);
    glVertex3fv(vertices[b]);
    glVertex3fv(vertices[c]);
    glVertex3fv(vertices[d]);
    glEnd();
}

void drawColorCube() {
    // Передняя грань (z = -1)
    drawFace(0, 3, 2, 1, faceColors[0][0], faceColors[0][1], faceColors[0][2]);
    // Правая грань (x = 1)
    drawFace(1, 2, 6, 5, faceColors[1][0], faceColors[1][1], faceColors[1][2]);
    // Задняя грань (z = 1)
    drawFace(5, 6, 7, 4, faceColors[2][0], faceColors[2][1], faceColors[2][2]);
    // Левая грань (x = -1)
    drawFace(0, 4, 7, 3, faceColors[3][0], faceColors[3][1], faceColors[3][2]);
    // Верхняя грань (y = 1)
    drawFace(3, 7, 6, 2, faceColors[4][0], faceColors[4][1], faceColors[4][2]);
    // Нижняя грань (y = -1)
    drawFace(0, 1, 5, 4, faceColors[5][0], faceColors[5][1], faceColors[5][2]);
}

// ==================== ФУНКЦИИ ПРОЕКЦИЙ ====================

void renderCubeInViewport(int x, int y, int w, int h, int projType) {
    glViewport(x, y, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    if (projType == 3) {
        // Перспективная проекция
        double aspect = (double)w / (double)h;
        gluPerspective(45.0, aspect, 1.0, 20.0);
    }
    else {
        // Ортографическая проекция для всех аксонометрических случаев
        glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    switch (projType) {
    case 0:
        // Фронтальная ортографическая проекция (без поворотов)
        break;

    case 1:
        // ИЗОМЕТРИЧЕСКАЯ ПРОЕКЦИЯ
        // θ = 35.264° (вокруг X), φ = 45° (вокруг Y)
        // fz = cos(θ) = 0.8165
        glRotatef(ISO_PHI, 0.0, 1.0, 0.0);      // Сначала поворот вокруг Y на 45°
        glRotatef(ISO_THETA, 1.0, 0.0, 0.0);    // Затем поворот вокруг X на 35.264°
        break;

    case 2:
        // ДИМЕТРИЧЕСКАЯ ПРОЕКЦИЯ
        // θ = 15.4° (вокруг X), φ = 16.0° (вокруг Y)
        // fz = sin(φ)·cos(θ) = 3/8 = 0.375
        glRotatef(DIM_PHI, 0.0, 1.0, 0.0);      // Поворот вокруг Y
        glRotatef(DIM_THETA, 1.0, 0.0, 0.0);    // Поворот вокруг X
        break;

    case 3:
        // ПЕРСПЕКТИВНАЯ ПРОЕКЦИЯ (управляемая камера)
        gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
        break;
    }

    drawColorCube();
}

// ==================== ОБРАБОТЧИКИ СОБЫТИЙ ====================

void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);  // Плоское затенение - цвета не перетекают

    int halfW = windowWidth / 2;
    int halfH = windowHeight / 2;

    // 1. Верхний левый угол - ФРОНТАЛЬНАЯ ОРТОГРАФИЯ
    renderCubeInViewport(0, halfH, halfW, halfH, 0);

    // 2. Верхний правый угол - ИЗОМЕТРИЯ (θ=35.264°, φ=45°, fz=0.8165)
    renderCubeInViewport(halfW, halfH, halfW, halfH, 1);

    // 3. Нижний левый угол - ДИМЕТРИЯ (θ=15.4°, φ=16.0°, fz=0.375)
    renderCubeInViewport(0, 0, halfW, halfH, 2);

    // 4. Нижний правый угол - ПЕРСПЕКТИВА
    renderCubeInViewport(halfW, 0, halfW, halfH, 3);

    glutSwapBuffers();
}

void reshape(int w, int h) {
    windowWidth = w;
    windowHeight = h;
    glViewport(0, 0, w, h);
}

void keyboard(unsigned char key, int x, int y) {
    float step = 0.3;
    switch (key) {
    case 'w': eyeY += step; break;
    case 's': eyeY -= step; break;
    case 'a': eyeX -= step; break;
    case 'd': eyeX += step; break;
    case 'q': eyeZ -= step; break;
    case 'e': eyeZ += step; break;
    case 'r':
        eyeX = 5.0; eyeY = 5.0; eyeZ = 5.0;
        break;
    case 27: // ESC
        exit(0);
        break;
    }
    glutPostRedisplay();
}


// ==================== ИНИЦИАЛИЗАЦИЯ ====================

void init() {
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_FLAT);  // Отключаем интерполяцию цветов
}

// ==================== ТОЧКА ВХОДА ====================

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow("Лабораторная работа №4 - Изометрия (fz=0.8165) и Диметрия (fz=3/8)");

    init();


    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);

    glutMainLoop();
    return 0;
}