Загрузка данных
#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;
}