Визуализация физики и математики на C++ с использованием SFML

Курс для начинающих по созданию физических симуляций и визуализации математических функций на C++. Вы изучите основы программирования, работу с библиотекой SFML и научитесь моделировать движение тел и гравитацию.

1. Основы C++ и настройка окна в SFML

Основы C++ и настройка окна в SFML

Добро пожаловать в мир, где математические формулы и физические законы оживают на экране монитора. Создание симуляций — это не просто написание кода, это конструирование собственной миниатюрной вселенной со своими правилами гравитации, столкновений и движения. Чтобы стать творцом такой вселенной, нам понадобятся два мощных инструмента: язык программирования C++ и графическая библиотека SFML.

Язык C++ славится своей высочайшей производительностью. Когда мы симулируем поведение тысяч сталкивающихся частиц или рассчитываем сложную орбиту планет, компьютеру приходится выполнять миллионы математических операций в секунду. C++ справляется с этим безупречно. Однако сам по себе этот язык не умеет рисовать графики или открывать окна — он работает только с текстом и числами в памяти.

Здесь на помощь приходит SFML (Simple and Fast Multimedia Library). Это библиотека, которая берет на себя всю черновую работу по общению с операционной системой: она создает окно, считывает нажатия клавиатуры и предоставляет нам удобный «холст» для рисования пикселей.

Анатомия простейшей программы на C++

Прежде чем рисовать физические тела, нужно понять, как вообще запускается программа. Любой код на C++ — это набор инструкций, который читает компилятор (специальная программа-переводчик) и превращает в понятный компьютеру машинный код.

Давайте посмотрим на минимальный каркас любой программы:

Разберем этот фундамент по кирпичикам:

  • #include <iostream> — это команда подключения внешних инструментов. Представьте, что вы собираетесь готовить торт. Эта строчка означает: «Достань с полки поваренную книгу с базовыми рецептами». В данном случае мы подключаем стандартную библиотеку для ввода и вывода текста.
  • int main() — это главная функция. Операционная система всегда ищет в коде место с названием main, чтобы начать выполнение программы именно оттуда. Это входная дверь в наше приложение.
  • Фигурные скобки {} обозначают границы функции. Все, что находится внутри них, будет выполнено шаг за шагом.
  • return 0; — это сигнал операционной системе о том, что программа завершила свою работу успешно (без ошибок). Ноль в программировании часто означает отсутствие проблем.
  • Создание графического окна

    Теперь заменим текстовый вывод на графику. Для этого мы подключим библиотеку SFML и попросим ее создать для нас окно.

    Вместо стандартной библиотеки мы подключили <SFML/Graphics.hpp>.

    Строка sf::RenderWindow window(...) создает объект окна. Мы передаем ему два важных параметра:

  • sf::VideoMode(800, 600) задает размер окна в пикселях (светящихся точках на экране). В нашем случае это 800 пикселей в ширину и 600 в высоту.
  • "Моя первая симуляция" — это текст, который появится в заголовке окна.
  • Если вы запустите этот код, окно мелькнет на долю секунды и исчезнет. Почему? Потому что компьютер выполняет инструкции с огромной скоростью. Он создал окно, дошел до команды return 0; и честно завершил программу. Нам нужно заставить окно оставаться открытым.

    Игровой цикл: сердце любой симуляции

    Чтобы окно не закрывалось, а симуляция жила во времени, используется концепция, называемая игровым циклом (game loop). Это бесконечное повторение трех базовых действий, пока пользователь не решит выйти из программы.

    > Игровой цикл — это бесконечный цикл в коде, который непрерывно обрабатывает действия пользователя, обновляет математическую модель мира и отрисовывает новый кадр на экране.

    !Схема игрового цикла: от обработки событий до отрисовки кадра

    Давайте напишем полноценный игровой цикл для нашего окна:

    Этот код — золотой стандарт, который мы будем использовать в каждой статье курса. Разберем его этапы:

    Этап 1: Обработка событий

    Команда while (window.isOpen()) заставляет программу работать до тех пор, пока окно открыто. Внутри мы создаем объект sf::Event (событие).

    Событие — это любое действие пользователя: движение мыши, нажатие клавиши на клавиатуре или клик по крестику закрытия окна. Функция window.pollEvent(event) проверяет, произошло ли что-то новое. Если пользователь нажал на крестик (sf::Event::Closed), мы вызываем команду window.close(), цикл прерывается, и программа завершается.

    Этапы 2-4: Двойная буферизация

    Команды clear и display работают в паре и реализуют принцип двойной буферизации.

    Представьте театральную сцену. Если декораторы будут менять декорации прямо на глазах у зрителей, магия спектакля разрушится. Вместо этого используется занавес.

  • window.clear(sf::Color::Black) — это закрытие занавеса и полная очистка сцены (заливка черным цветом).
  • Далее в коде мы будем расставлять «декорации» — рисовать круги, линии и графики. Зритель этого процесса не видит, все происходит в скрытой памяти видеокарты.
  • window.display() — это мгновенное открытие занавеса. Зритель видит уже готовую, идеально отрисованную картинку.
  • Этот процесс повторяется десятки раз в секунду (обычно 60 кадров в секунду), создавая иллюзию плавного движения.

    Экранная система координат

    Последний, но критически важный концепт на сегодня — это то, как компьютер понимает пространство.

    В школьной математике мы привыкли к декартовой системе координат. В ней точка отсчета находится в центре, ось идет вправо, а ось идет вверх.

    В компьютерной графике все иначе. Исторически сложилось так, что изображение на старых телевизорах и мониторах рисовалось электронным лучом слева направо и сверху вниз. Поэтому экранная система координат перевернута:

    | Характеристика | Школьная математика | Компьютерная графика (SFML) | | :--- | :--- | :--- | | Точка | В центре графика | В левом верхнем углу окна | | Ось | Растет вправо | Растет вправо | | Ось | Растет вверх | Растет вниз |

    !Интерактивное сравнение математических и экранных координат

    Если мы создали окно размером 800 на 600 пикселей:

  • Левый верхний угол имеет координаты .
  • Правый верхний угол: .
  • Левый нижний угол: .
  • Правый нижний угол: .
  • Точный центр экрана: .
  • Понимание того, что ось направлена вниз, убережет вас от множества ошибок при симуляции гравитации. Если вы захотите, чтобы мячик падал вниз, вам нужно будет увеличивать его координату , а не уменьшать, как мы привыкли на уроках физики.

    Сегодня мы заложили прочный фундамент. Мы настроили компилятор, создали окно, запустили бесконечный игровой цикл и разобрались с перевернутыми координатами. В следующей статье мы используем этот холст, чтобы нарисовать наши первые геометрические фигуры и заставить их двигаться с помощью математических векторов.