Для работы проекта потребуются:
- CMake version 3.8
- GoogleTest
Для установки
git clone git@github.com:Pelmeshka127/Triangles-3D.git
cd Triangles-3D
Запуск через CMake
cmake -B build
cd build/src/
cmake --build .
./triangles
В данный момент дорабатывается версия для CMake.
Со стандартного ввода приходит число 0 < N < 1000000, а потом N наборов точек, представляющих трёхмерные треугольники. Задача: вывести номера всех треугольников, которые пересекаются с каким-либо другим.
Для исследования взаимного расположения треугольников в пространстве рассмотрим 3 взаимоисключающие ситуации:
Если плоскости, в которых лежат треугольники параллельны, то треугольники не пересекаются.
Если же плоскости совпадают, то сначала проверим каждый отрезок одного треугольника на пересечение с каждым отрезком другого треугольника(прочитать о реализации этого алгоритма можно в книге Томаса Кормена "Алгоритмы: построение и анализ" в разделе вычислительной геометрии). Если отрезки не пересекаются, то надо проверить не лежит ли один треугольник внутри другого. Если же и этот вариант не проходит, то пересечения нет.
Этот случай стоит рассмотреть отдельно, для облегчения алгоритма из следующего пункта. Здесь мы находим расстояние от точек одного треугольника до плоскости другого (знаковое расстояние, не по модулю). Если все расстояния имеют один знак и не равны нулю, то треугольники не пересекаются.
Если не выполняются предыдущие пункты, то остается только вариант, когда треугольники пересекаются по линии пересечения их плоскостей. Сначала мы находим прямую пересечения, затем на этой прямой находим отрезки, по которым треугольники пересекают плоскость. Если отрезки каким-либо образом перекрывают друг друга, то пересечение есть, иначе - нет.(Идея этого алгоритма рассказывается в книге Philip J. Scneider "Geometric tools for computer graphics" в разделе о пересечении треугольников в 3D).
У нас есть алгоритм, который дает ответ на вопрос, пересекаются ли два треугольника между собой. Но в нашей задаче треугольников может быть огромное количество и искать пересечение каждого с каждым - не самая лучшая идея(по факту это O(N^2)). Для ускорения поиска пересекающихся треугольников используется октодерево. Подробно прочитать о нем можно здесь. Если коротко, то мы разбиваем наше пространство на другие подпространства и ищем пересечения треугольников внутри этих подпространств. Треугольники из одного подпространства не могут пересекаться с треугольниками из другого, поэтому мы проверять их не будем, что ускорит работу алгоритма).