Skip to content

vazgensoghoyan/fractal-renderer

Repository files navigation

🇬🇧 ENGLISH VERSION: README in English

Fractal Renderer & Math Engine (C++)

Модульный C++ проект для генерации фракталов, работы с математическими примитивами и рендеринга изображений в BMP.

Фокус на чистой архитектуре, использовании паттернов, обобщённом дизайне (concepts, templates), численных алгоритмах и расширяемости.

Проект демонстрирует:

  • современный C++ (C++20/23),
  • использование принципов ООП,
  • некоторые паттерны проектирования (билдер, фабричный метод, адаптер, пр.)
  • использование концептов,
  • математику (комплексные числа, кватернионы, фракталы),
  • работу с бинарными форматами изображений,
  • модульную архитектуру и тесты.

Содержание


Примеры рендеров

Mandelbrot Julia

Пример использования функционала

Создание рендерера происходит через паттерна Fluent Builder. Для раскраски фрактала используется конкретная структура BgrColorizer, которая реализует концепт специального вида. Для рендерера задаются нужные свойства (свойства viewport-а, нужные функции и пр.) и билдится.

Пример ниже иллюстрирует рисование фрактала Мандельброта.

auto renderer = 
    FractalRendererBuilder<BgrColorizer>
        ::get_builder()
            .set_viewport_width(3)
            .set_viewport_center(-0.75)
            .set_iteration_func( [](auto& z, auto& c) { return z * z + c; } )
            .set_initial_func( [](auto&) { return Complex::Zero(); } )
            .set_param_func( [](auto& pixel) { return pixel; } )
            .build();

Bmp image = Bmp::empty(2000, 2000);
renderer.render(image);

io::save(image, "mandelbrot_set.bmp");

Сборка

git clone --recurse-submodules git@github.com:vazgensoghoyan/fractal-renderer.git
cd fractal-renderer

mkdir build && cd build   # Создаем папку для сборки и переходим в нее
cmake ..                  # Генерируем сборку через CMake
cmake --build .           # сборка всех целей (библиотека + приложение + тесты + примеры)
ctest                     # (Опционально) Запуск тестов через CTest

После полной сборки имеем следующие исполняемые файлы:

  • ./iheay_app
  • usage_examples/
    • ./draw_julia_set
    • ./draw_mandelbrot_set
    • ./render_animation_mandelbrot
  • tests/
    • bmp/
      • ./test_bmp
    • math/
      • ./test_vec3
      • ./test_complex
      • ./test_quaternion

Структура репозитория

fractal-renderer/
│
├── external/           # git submodules (third-party зависимости)
│   ├── googletest/
│   └── raylib/
│
├── include/
│   ├── adapters/
│   ├── bmp/            # структуры формата BMP и IO-функционал
│   ├── fractal/        # алгоритмы рендера фракталов
│   ├── math/           # Vec3, Complex, Quaternion, Ray
│   ├── rasterizer/     # концепт PixeledImage и алгоритмы растеризации к нему
│   ├── ray_tracing/    # движок рей трейсинга (пока почти пуст)
│   └── utils/          # пока тут лишь Logger
│
├── src/                # реализации
│   ├── ...
│   └── main.cpp
│
├── tests/
│   ├── bmp/            # тесты для модуля BMP
│   ├── math/           # тесты для модуля математики
│   └── CMakeLists.txt
│
├── usage_examples/     # небольшие примеры использования функционала
│   ├── CMakeLists.txt
│   ├── draw_julia_set.cpp
│   ├── draw_mandelbrot_set.cpp
│   └── render_animation_mandelbrot.cpp
│
├── CMakeLists.txt
└── README.md

Основные возможности

Математическое ядро

Собственная реализация математических примитивов (расскажу чуть подробнее лишь про один):

  • Complex — комплексные числа Поддерживает:

    • алгебраическую и тригонометрическую формы (именованные конструкторы)
    • арифметические операции (+, −, *, /)
    • модуль, аргумент (нормализован), взятие сопряженного
    • возведение в степень
    • извлечение n-корней
    • сравнение с учётом EPS
    • форматированный вывод через std::format
    • широко используются constexpr и [[nodiscard]]
  • Quaternion

  • Vec3

  • Ray

Это ядро может использоваться независимо от фракталов — как мини-библиотека для численных и графических задач.


Работа с изображениями (BMP)

Реализован собственный минималистичный модуль для работы с 24-bit BMP:

Возможности

  • Загрузка и сохранение BMP без сторонних библиотек
  • Поддержка только:
    • 24 bpp
    • без сжатия (BI_RGB)
  • Явная работа со структурами заголовков BMP
  • Контроль над выравниванием структур через #pragma pack

Класс Bmp

Универсальное представление растрового изображения:

Bmp image = Bmp::empty(1920, 1080);
image.set_pixel(x, y, {b, g, r});

Bmp image2 = Bmp::empty(4000, 4000, colors::WHITE);
BgrPixel pixel = image2.get_pixel(12, 122);
image2.try_set_pixel(-10, 1, {b, g, r}); // no exception, returns true if set

namespace bmp::io

Решил, что будет правильно вынести логику загрузки и выгрузки bmp файлов из класса, этим стремлюсь соблюдать принцип Single Responsibility.

Bmp image = io::load("some/interesting/path");
// преобразования
io::save(image, "some/unique/path");

Фрактальный рендерер

Обобщённый движок рендеринга фракталов не зависит ни от формата изображения, ни от конкретной формулы фрактала — оба аспекта задаются снаружи через обобщённые параметры:

Компонент Отвечает за
IterationFunc Формула итерации (например, z = z² + c)
InitialFunc Начальное значение z_0
ParamFunc Параметр фрактала (например, c для Julia)
Colorizer Преобразование числа итераций → цвет

Это позволяет строить:

  • множество Мандельброта
  • множества Жюлиа
  • кастомные фракталы с любыми формулами

Система раскраски (Colorizer Concept)

Используется C++ concepts для задания требований к colorizer-а:

template <typename Colorizer>
concept ColorizerConcept = requires(Colorizer c, double mu, int max_iter) {
    typename Colorizer::pixel_type;
    { c(mu, max_iter) } -> std::same_as<typename Colorizer::pixel_type>;
};

Рендерер не знает ничего о формате изображения — только о том, что есть pixel_type (так как они могут быть произвольные, в нашем случае для Bmp используется bgr-формат). Это позволяет использовать любой тип изображения, удовлетворяющий концепту PixeledImage.


Анимация фракталов

Добавлена система ключевых кадров:

struct FractalKeyframe {
    Viewport viewport;
    FractalConfig config;
    math::Complex julia_c;
};

Поддерживается интерполяция между состояниями:

FractalKeyframe k = interpolate(a, b, t);

Это основа для генерации зум-анимаций и морфинга фракталов.


Обобщённый рендеринг через Concepts

Рендерер работает с любым типом изображения, удовлетворяющим:

template<typename Image>
concept PixeledImage = requires(Image image, int x, int y, Image::pixel_type pixel) {
    typename Image::pixel_type;
    { image.width() } -> std::convertible_to<int>;
    { image.height() } -> std::convertible_to<int>;
    { image.set_pixel(x, y, pixel) };
};

Это полностью отделяет логику фрактала от способа хранения и вывода изображения.


Логирование

Минималистичный потокобезопасный логгер:

  • Уровни: INFO, WARN, DEBUG, ERROR
  • Цветной вывод в консоль
  • Форматирование через std::format
  • Защита через std::mutex
LOG_INFO("Rendering started: {}x{}", width, height);

Можно полностью отключить через макрос LOGGING_ENABLED, когда нужна большая производительность.


Используемые технологии

  • C++20/23
  • Concepts
  • Templates
  • OpenMP
  • CMake
  • GoogleTest

Тестирование

Проект покрыт unit-тестами на базе GoogleTest:

  • математические классы (Complex, Quaternion, Vec3)
  • классы работы с Bmp

Архитектурные особенности

✔ Разделение математики, рендеринга и вывода ✔ Минимальные зависимости ✔ Обобщённый дизайн через concepts ✔ Расширяемость через функции высшего порядка ✔ Чёткий контроль над бинарными структурами ✔ Подходит как база для:

  • фрактальных визуализаторов
  • CPU-рендереров
  • учебных проектов по численным методам

Ограничения

  • Поддерживается только 24-bit BMP без сжатия
  • Выравнивание структур ориентировано на little-endian архитектуры (типично x86)
  • Рендеринг выполняется на CPU

Возможные направления развития

  • GPU-рендеринг (CUDA / OpenCL)
  • Мультипоточный тайлинг
  • Интерактивный viewer с возможностью подвигать ползунки (SDL / ImGui)
  • Поддержка 3D-фракталов с использованием кватернионов

About

A modular C++ project for fractal generation, mathematical primitives, and rendering images in BMP format.

Topics

Resources

License

Stars

Watchers

Forks

Contributors