Я бы сказал, что вы на правильном пути, но придумать оптимальный и / или эффективный алгоритм - это другое дело: это сложная проблема. Однако, если ваш интерес не является академическим, может оказаться достаточно хорошего решения.
Во-первых, если вы не заинтересованы в разработке собственного решения, CGAL уже содержит алгоритм для декомпозиции выпуклых многогранников: http://doc.cgal.org/latest/Convex_decomposition_3/index.html.
Теперь о методе; Как и многие проблемы в 3D, часто полезно рассмотреть проблему 2D, которая легче понять. Для 2D задача состоит в том, чтобы идентифицировать рефлекторные вершины и разбить многоугольник на две части, создав новое ребро (и, возможно, новые вершины) из этой рефлекторной вершины и продолжая, пока у вас не останется никаких рефлекторных вершин (и, следовательно, полностью выпуклых многоугольников). ).
Разложение полигонов Дж. Марка Кейла содержит следующий алгоритм (в неоптимизированном виде):
diags = decomp(poly)
min, tmp : EdgeList
ndiags : Integer
for each reflex vertex i
for every other vertex j
if i can see j
left = the polygon given by vertices i to j
right = the polygon given by vertices j to i
tmp = decomp(left) + decomp(right)
if(tmp.size < ndiags)
min = tmp
ndiags = tmp.size
min += the diagonal i to j
return min
По сути, он исчерпывающе сравнивает все возможные разделы и возвращает тот, который имеет наименьшее количество произведенных диагоналей. В этом смысле это несколько грубая сила, а также оптимальная.
Если вам нужны «более приятные» декомпозиции, то есть те, которые производят более компактные формы, а не вытянутые, вы можете также рассмотреть эту, созданную Марком Баязитом , которая является жадной (следовательно, намного более быстрой) и выглядит лучше, но имеет несколько недостатков. Он в основном работает, пытаясь соединить рефлекторные вершины с лучшей, противоположной ей, обычно с другой рефлекторной вершиной:
Одним из недостатков является то, что он игнорирует «лучшие» декомпозиции, создавая точки Штейнера (точки, которые не существуют на существующем ребре):
Проблема в 3D может быть похожей; вместо рефлекторных вершин вы определяете «края надреза». Наивной реализацией было бы выявить края надрезов и многократно выполнять плоские разрезы на многограннике, пока все многогранники не выпуклые. Проверьте "Выпуклые разбиения многогранников: нижняя граница и оптимальный алгоритм наихудшего случая" Бернарда Шазеля для получения дополнительной информации.
Обратите внимание, что этот подход может привести к наихудшему случаю экспоненциального числа субполиэдров. Это потому, что вы можете иметь вырожденные случаи, подобные этому:
Но если у вас нетривиальная сетка (например, неровная поверхность), вы все равно получите плохие результаты. Весьма вероятно, что вы захотите сделать много упрощений заранее, если вам когда-либо понадобится использовать это для сложных сеток.