Hexagonal Grid Pathfinding & Maze Visualization on Interactive Maps
Features | How It Works | Installation | Usage | Architecture | API Docs
qHexWalker is a Qt 6 desktop application that combines Uber's H3 hexagonal indexing system with MapLibre maps to provide:
- Interactive hexagonal grid visualization at multiple resolutions
- Procedural maze generation using Prim's algorithm on hex grids
- Bidirectional A pathfinding* with hierarchical resolution refinement
- Multi-waypoint route planning with real-time visualization
video.mp4
| Feature | Description |
|---|---|
| H3 Hexagonal Grid | Visualize Uber's hierarchical spatial index (resolutions 3-15) |
| Bidirectional A* | Fast pathfinding that searches from both ends simultaneously |
| Maze Generation | Procedural mazes using randomized Prim's algorithm |
| Multi-Waypoint Routing | Plan routes through multiple destinations |
| Real-time Visualization | Watch the algorithm explore cells as it searches |
| Search Statistics | View explored cells count, time, and path length |
| Dark Theme UI | Modern Material Design interface |
H3 divides the Earth into hexagonal cells at 16 resolutions (0-15). Hexagons provide uniform distance to neighbors and better tessellation than squares.
Resolution │ Avg. Hex Area │ Hex Count
────────────┼─────────────────┼──────────────
3 │ 12,392 km² │ 41,162
7 │ 5.16 km² │ 98M
10 │ 14,950 m² │ 23B
15 │ 0.9 m² │ 569T
The pathfinding uses bidirectional A* with hierarchical resolution refinement:
┌─────────────────────────────────────────────────────────────────────┐
│ BIDIRECTIONAL A* SEARCH │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ START ──────────────► ◄────────────── GOAL │
│ │ │ │
│ ▼ ▼ │
│ ┌────────┐ ┌────────┐ │
│ │Forward │ │Backward│ │
│ │ Search │ MEET │ Search │ │
│ │ │◄────────────►│ │ │
│ └────────┘ └────────┘ │
│ │ │ │
│ └────────────┬───────────┘ │
│ ▼ │
│ ┌──────────────┐ │
│ │ Optimal Path │ │
│ └──────────────┘ │
│ │
│ Complexity: O(b^(d/2)) instead of O(b^d) │
└─────────────────────────────────────────────────────────────────────┘
To optimize performance, the algorithm uses multi-resolution search:
Step 1: Coarse Search (Resolution 3)
┌───────────────────────────────────┐
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ │────►│ │────►│ │ │
│ └─────┘ └─────┘ └─────┘ │
│ START GOAL │
└───────────────────────────────────┘
│
▼
Step 2: Refine Path (Higher Resolution)
┌─────────────────────────────────────────┐
│ ⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡─⬡ │
│ Detailed path at target │
│ resolution with all cells │
└─────────────────────────────────────────┘
The maze generator creates perfect mazes on hexagonal grids:
┌─────────────────────────────────────────────────────────────────────┐
│ RANDOMIZED PRIM'S ALGORITHM │
├─────────────────────────────────────────────────────────────────────┤
│
│ 1. Create Room Grid 2. Initialize with Random Room
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│ · · · · · · · · · · · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ■ · ⬡ · ⬡ ← Start room
│ · · · · · · · · · · · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│
│ 3. Add Walls to Frontier 4. Connect Rooms Through Walls
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│ · · W · · · · · · │ · · · ·
│ ⬡ W ■ W ⬡ · ⬡ ⬡───■───⬡ · ⬡
│ · · W · · · · · · │ · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│
│ 5. Repeat Until All Connected
│ ⬡───⬡───⬡───⬡
│ │ │
│ ⬡ ⬡───⬡ ⬡ Perfect maze with
│ │ │ │ single solution path
│ ⬡───⬡ ⬡───⬡
│
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ APPLICATION LAYERS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ QML UI Layer │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │ │
│ │ │ Target List │ │ Map View │ │ Statistics │ │ │
│ │ └─────────────┘ └──────────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Qt Models Layer │ │
│ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ H3Model │ │ H3TargetsModel │ │ │
│ │ │ (QAbstractListModel)│ │ (QAbstractListModel) │ │ │
│ │ └─────────────────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Business Logic Layer │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │ │
│ │ │ H3Worker │ │ H3MazeAdapter│ │ MapProvider │ │ │
│ │ │ (Thread) │ │ (Async) │ │ (Style/Source) │ │ │
│ │ └──────────┘ └──────────────┘ └───────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Algorithm Layer │ │
│ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ H3AStar │ │ H3MazeGenerator │ │ │
│ │ │ (Bidirectional A*) │ │ (Prim's Algorithm) │ │ │
│ │ └─────────────────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────┐ ┌─────────────────┐
│ Main Thread │ │ Worker Thread │
│ (Qt Event │ │ (H3Worker) │
│ Loop + UI) │ │ │
├─────────────────┤ ├─────────────────┤
│ │ request │ │
│ User Click ────┼─────────►│ A* Search │
│ │ │ │ │
│ │ signal │ ▼ │
│ Update UI ◄───┼──────────│ Path Result │
│ │ │ │
└─────────────────┘ └─────────────────┘
| Component | Version | Notes |
|---|---|---|
| CMake | >= 3.19 | Build system |
| C++ Compiler | C++20 | GCC 15+, Clang 17+ |
| Qt | 6.5+ | QuickControls2, Sql, Positioning |
| vcpkg | Latest | Package manager |
| MapLibre Native Qt | Latest | Map rendering |
- H3 - Hexagonal hierarchical spatial index
- spdlog - Fast logging library
- GTest - Unit testing (optional)
- Google Benchmark - Performance testing (optional)
# Linux (Ubuntu/Debian)
sudo apt install qt6-base-dev qt6-declarative-dev qt6-positioning-dev
# macOS
brew install qt@6
# Windows
# Use Qt Online Installergit clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh # Linux/macOS
# or bootstrap-vcpkg.bat on Windowsgit clone https://github.com/maplibre/maplibre-native-qt.git
cd maplibre-native-qt
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local/maplibre-native-qt" \
-DCMAKE_PREFIX_PATH="/path/to/Qt/6.x.x/<platform>" \
-DMLN_WITH_OPENGL=ON \
-DCMAKE_TOOLCHAIN_FILE="/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake"
cmake --build build -j
cmake --install buildgit clone https://github.com/wecand0/qHexWalker.git
cd qHexWalker
export VCPKG_ROOT="/path/to/vcpkg"
export QT_PREFIX="/path/to/Qt/6.x.x/<platform>"
export MAPLIBRE_PREFIX="$HOME/.local/maplibre-native-qt"
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DCMAKE_PREFIX_PATH="${QT_PREFIX};${MAPLIBRE_PREFIX}" \
-DBUILD_TESTS=ON \
-DBENCHMARK_ENABLE=ON
cmake --build build -j| Option | Default | Description |
|---|---|---|
BUILD_TESTS |
OFF | Build unit tests |
BENCHMARK_ENABLE |
OFF | Build benchmarks |
DEBUG |
OFF | Debug build with symbols |
./build/QHexWalker┌────────────────────────────────────────────────────────────────────┐
│ qHexWalker ─ □ X│
├─────────────┬──────────────────────────────────────────────────────┤
│ WAYPOINTS │ │
│ │ │
│ 1. [12] ▲▼ │ ╭─────────────────────────╮ │
│ 47.12°N │ ╱ ╲ │
│ 38.94°E │ │ ⬡ ⬡ ⬡ ⬡ ⬡ ⬡ │ │
│ │ │ ⬡ ■ ■ ■ ■ ⬡ ⬡ │ │
│ 2. [12] ▲▼ │ │ ⬡ ■ ○───────● ⬡ │ │
│ 47.15°N │ │ ⬡ ■ ■ ■ ■ ⬡ ⬡ │ │
│ 38.97°E │ │ ⬡ ⬡ ⬡ ⬡ ⬡ ⬡ │ │
│ │ ╲ ╱ │
│ [Remove] │ ╰─────────────────────────╯ │
│ │ │
├─────────────┤ ○ Start ● Goal ■ Wall ─ Path │
│ STATISTICS │ │
│ Cells: 847 │ MAP │
│ Time: 23ms │ │
│ Path: 156 │ │
└─────────────┴──────────────────────────────────────────────────────┘
- Click on map to add waypoints
- Generate maze (optional) for obstacle-based routing
- View path computed automatically between waypoints
- Reorder waypoints using arrow buttons
- Monitor statistics for algorithm performance
qHexWalker/
├── src/
│ ├── core/
│ │ ├── main.cpp # Entry point
│ │ ├── application.h/cpp # Application class
│ │ ├── entryPoint.h/cpp # UI initialization
│ │ ├── mapProvider.h/cpp # Map source management
│ │ └── logger.h # Logging utilities
│ └── models/
│ ├── astar.h/cpp # Bidirectional A* (547 lines)
│ ├── dijkstra.h/cpp # Dijkstra's algorithm
│ ├── h3Model.h/cpp # Hex cells model
│ ├── h3TargetsModel.h/cpp # Waypoints model
│ ├── h3Cell.h/cpp # Cell data class
│ ├── h3Target.h/cpp # Target data class
│ ├── h3Worker.h/cpp # Threading wrapper
│ ├── h3MazeGenerator.h/cpp # Maze generation
│ ├── h3MazeAdapter.h/cpp # Maze orchestration
│ └── helper.h/cpp # H3 geometry utilities
├── ui/
│ └── main.qml # QML interface
├── tests/
│ ├── maze_test.cpp # Maze tests
│ └── astar_test.cpp # A* tests
├── benchmark/
│ ├── maze_benchmark.cpp # Maze benchmarks
│ └── path_benchmark.cpp # Pathfinding benchmarks
├── CMakeLists.txt
├── vcpkg.json
└── README.md
| Approach | Time Complexity | Improvement |
|---|---|---|
| Standard A* | O(b^d) | Baseline |
| Bidirectional A* | O(b^(d/2)) | ~50% reduction |
| + Resolution Hierarchy | O(b^(d/4)) | ~75% reduction |
Where b = branching factor (6 for hexagons), d = path depth
Run benchmarks:
./build/qhexwalker_benchmark| Error | Solution |
|---|---|
Could not find QMapLibre |
Add MapLibre prefix to CMAKE_PREFIX_PATH |
Could not find Qt6::Positioning |
Install Qt Positioning module |
vcpkg toolchain not found |
Check path to vcpkg.cmake |
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
Поиск пути и визуализация лабиринтов на гексагональных сетках
qHexWalker — это десктопное Qt 6 приложение, объединяющее систему гексагональной индексации H3 от Uber с картами MapLibre:
- Интерактивная визуализация гексагональных сеток разных разрешений
- Процедурная генерация лабиринтов алгоритмом Прима
- Двунаправленный A* с иерархическим уточнением пути
- Планирование маршрутов через множество точек с визуализацией в реальном времени
| Функция | Описание |
|---|---|
| H3 Гексагональная сетка | Визуализация иерархического пространственного индекса (разрешения 3-15) |
| Двунаправленный A* | Быстрый поиск пути одновременно с двух концов |
| Генерация лабиринтов | Процедурные лабиринты алгоритмом Прима |
| Многоточечная маршрутизация | Планирование маршрутов через несколько целей |
| Визуализация в реальном времени | Наблюдайте за работой алгоритма |
| Статистика поиска | Количество ячеек, время, длина пути |
| Тёмная тема | Современный Material Design интерфейс |
H3 делит Землю на гексагональные ячейки с 16 уровнями разрешения (0-15). Гексагоны обеспечивают равномерное расстояние до соседей и лучшую тесселяцию, чем квадраты.
Разрешение │ Средняя площадь │ Количество ячеек
────────────┼───────────────────┼───────────────────
3 │ 12,392 км² │ 41,162
7 │ 5.16 км² │ 98 млн
10 │ 14,950 м² │ 23 млрд
15 │ 0.9 м² │ 569 трлн
Поиск пути использует двунаправленный A* с иерархическим уточнением разрешения:
┌─────────────────────────────────────────────────────────────────────┐
│ ДВУНАПРАВЛЕННЫЙ ПОИСК A* │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ СТАРТ ──────────────► ◄────────────── ЦЕЛЬ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────┐ ┌────────┐ │
│ │Прямой │ │Обратный│ │
│ │ поиск │ ВСТРЕЧА │ поиск │ │
│ │ │◄────────────►│ │ │
│ └────────┘ └────────┘ │
│ │ │ │
│ └────────────┬───────────┘ │
│ ▼ │
│ ┌───────────────┐ │
│ │Оптимальный путь│ │
│ └───────────────┘ │
│ │
│ Сложность: O(b^(d/2)) вместо O(b^d) │
└─────────────────────────────────────────────────────────────────────┘
Генератор создаёт идеальные лабиринты на гексагональных сетках:
┌─────────────────────────────────────────────────────────────────────┐
│ РАНДОМИЗИРОВАННЫЙ АЛГОРИТМ ПРИМА │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Создание сетки комнат 2. Инициализация случайной комнатой │
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│ · · · · · · · · · · · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ■ · ⬡ · ⬡ ← Старт
│ · · · · · · · · · · · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│
│ 3. Добавление стен 4. Соединение комнат
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│ · · W · · · · · · │ · · · ·
│ ⬡ W ■ W ⬡ · ⬡ ⬡───■───⬡ · ⬡
│ · · W · · · · · · │ · · · ·
│ ⬡ · ⬡ · ⬡ · ⬡ ⬡ · ⬡ · ⬡ · ⬡
│
│ 5. Повторение до соединения всех комнат
│ ⬡───⬡───⬡───⬡
│ │ │
│ ⬡ ⬡───⬡ ⬡ Идеальный лабиринт с
│ │ │ │ единственным решением
│ ⬡───⬡ ⬡───⬡
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ СЛОИ ПРИЛОЖЕНИЯ │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Слой QML UI │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │ │
│ │ │Список точек │ │ Карта │ │ Статистика │ │ │
│ │ └─────────────┘ └──────────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Слой Qt моделей │ │
│ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ H3Model │ │ H3TargetsModel │ │ │
│ │ │ (QAbstractListModel)│ │ (QAbstractListModel) │ │ │
│ │ └─────────────────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Слой бизнес-логики │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │ │
│ │ │ H3Worker │ │ H3MazeAdapter│ │ MapProvider │ │ │
│ │ │ (Поток) │ │ (Async) │ │ (Стили/источники) │ │ │
│ │ └──────────┘ └──────────────┘ └───────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Слой алгоритмов │ │
│ │ ┌─────────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ H3AStar │ │ H3MazeGenerator │ │ │
│ │ │(Двунаправленный A*) │ │ (Алгоритм Прима) │ │ │
│ │ └─────────────────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
| Компонент | Версия | Примечание |
|---|---|---|
| CMake | >= 3.19 | Система сборки |
| C++ компилятор | C++20 | GCC 15+, Clang 17+ |
| Qt | 6.5+ | QuickControls2, Sql, Positioning |
| vcpkg | Последняя | Менеджер пакетов |
| MapLibre Native Qt | Последняя | Рендеринг карт |
# Linux (Ubuntu/Debian)
sudo apt install qt6-base-dev qt6-declarative-dev qt6-positioning-dev
# macOS
brew install qt@6
# Windows — используйте Qt Online Installergit clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh # Linux/macOSgit clone https://github.com/maplibre/maplibre-native-qt.git
cd maplibre-native-qt
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/.local/maplibre-native-qt" \
-DCMAKE_PREFIX_PATH="/путь/к/Qt/6.x.x/<platform>" \
-DCMAKE_TOOLCHAIN_FILE="/путь/к/vcpkg/scripts/buildsystems/vcpkg.cmake"
cmake --build build -j
cmake --install buildgit clone https://github.com/wecand0/qHexWalker.git
cd qHexWalker
export VCPKG_ROOT="/путь/к/vcpkg"
export QT_PREFIX="/путь/к/Qt/6.x.x/<platform>"
export MAPLIBRE_PREFIX="$HOME/.local/maplibre-native-qt"
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" \
-DMLN_WITH_OPENGL=ON \
-DCMAKE_PREFIX_PATH="${QT_PREFIX};${MAPLIBRE_PREFIX}"
cmake --build build -j| Подход | Временная сложность | Улучшение |
|---|---|---|
| Стандартный A* | O(b^d) | Базовый |
| Двунаправленный A* | O(b^(d/2)) | ~50% снижение |
| + Иерархия разрешений | O(b^(d/4)) | ~75% снижение |
Где b = коэффициент ветвления (6 для гексагонов), d = глубина пути
| Ошибка | Решение |
|---|---|
Could not find QMapLibre |
Добавьте путь MapLibre в CMAKE_PREFIX_PATH |
Could not find Qt6::Positioning |
Установите модуль Qt Positioning |
vcpkg toolchain not found |
Проверьте путь к vcpkg.cmake |
Made with C++20, Qt 6, H3 and 💚