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


#include <windows.h>
#include <GL/glut.h>
#include <cmath>
#include <vector>
#include <string>

// Структура для хранения точки
struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) {}
};

// Глобальные переменные для кривой дракона
std::vector<Point> dragonPoints;
int dragonLevel = 12;              // уровень детализации (оптимально 10-14)
double dragonStartX = -0.3;        // начальная позиция
double dragonStartY = 0.0;
double dragonSize = 0.8;           // масштаб кривой

// Шаг черепашьей графики для кривой дракона (L-система)
void dragonTurtle(std::vector<Point>& points, double& x, double& y,
                  double& angle, double step, const std::string& str) {
    for (char c : str) {
        if (c == 'F') {
            // Двигаемся вперёд и добавляем точку
            double rad = angle * M_PI / 180.0;
            x += step * cos(rad);
            y += step * sin(rad);
            points.push_back(Point(x, y));
        } else if (c == '+') {
            // Поворот вправо на 90°
            angle += 90.0;
        } else if (c == '-') {
            // Поворот влево на 90°
            angle -= 90.0;
        }
        // Символы X и Y игнорируются при отрисовке — они только для рекурсии
    }
}

// Рекурсивное построение L-строки для кривой дракона
// Аксиома: FX
// Правила: X -> X+YF+
//          Y -> -FX-Y
std::string generateDragonLSystem(int level) {
    std::string current = "FX";
    for (int i = 0; i < level; i++) {
        std::string next;
        for (char c : current) {
            if (c == 'X') {
                next += "X+YF+";
            } else if (c == 'Y') {
                next += "-FX-Y";
            } else {
                next += c;  // F, +, - копируем как есть
            }
        }
        current = next;
    }
    return current;
}

// Построение массива точек кривой дракона
void buildDragonCurve() {
    dragonPoints.clear();
    std::string lstring = generateDragonLSystem(dragonLevel);
    
    double x = dragonStartX;
    double y = dragonStartY;
    double angle = 0.0;  // начальный угол (в градусах)
    // Длина шага уменьшается с ростом уровня, чтобы кривая помещалась в окно
    double step = dragonSize / pow(sqrt(2.0), dragonLevel);
    
    dragonPoints.push_back(Point(x, y));
    dragonTurtle(dragonPoints, x, y, angle, step, lstring);
}

// Функция отрисовки
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Рисуем координатные оси (серые)
    glColor3f(0.3f, 0.3f, 0.3f);
    glBegin(GL_LINES);
    glVertex2f(-1.0f, 0.0f); glVertex2f(1.0f, 0.0f);
    glVertex2f(0.0f, -1.0f); glVertex2f(0.0f, 1.0f);
    glEnd();
    
    // Рисуем кривую дракона
    if (!dragonPoints.empty()) {
        glColor3f(0.2f, 0.8f, 1.0f);  // голубой цвет
        glLineWidth(1.5f);
        glBegin(GL_LINE_STRIP);
        for (const Point& p : dragonPoints) {
            glVertex2d(p.x, p.y);
        }
        glEnd();
    }
    
    glFlush();
}

// Обработка изменения размеров окна
void reshape(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    double aspect = (double)w / h;
    if (aspect >= 1.0) {
        gluOrtho2D(-aspect, aspect, -1.0, 1.0);
    } else {
        gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

// Обработка клавиатуры
void keyboard(unsigned char key, int x, int y) {
    switch (key) {
        case '1': dragonLevel = 8;  buildDragonCurve(); break;
        case '2': dragonLevel = 10; buildDragonCurve(); break;
        case '3': dragonLevel = 12; buildDragonCurve(); break;
        case '4': dragonLevel = 14; buildDragonCurve(); break;
        case '+': 
            if (dragonLevel < 16) {
                dragonLevel++;
                buildDragonCurve();
            }
            break;
        case '-': 
            if (dragonLevel > 1) {
                dragonLevel--;
                buildDragonCurve();
            }
            break;
        case 27: // Esc
            exit(0);
    }
    glutPostRedisplay();
}

// Инициализация
void init() {
    glClearColor(0.05f, 0.05f, 0.1f, 1.0f);  // тёмно-синий фон
    buildDragonCurve();
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(900, 900);
    glutInitWindowPosition(100, 50);
    glutCreateWindow("Dragon Curve - Harter-Heighway");
    
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
    
    printf("Dragon Curve Controls:\n");
    printf("  1-4 : preset levels (8, 10, 12, 14)\n");
    printf("  +/- : increase/decrease detail level\n");
    printf("  ESC : exit\n");
    
    glutMainLoop();
    return 0;
}