Создание OOBB из точек

Как создать минимальный OOBB для заданных точек? Создание AABB или сферы очень просто, но у меня проблемы с созданием минимального OOBB.

[править]

Первый ответ не принес мне хороших результатов. У меня нет огромного облака очков. У меня мало очков. Я делаю генерацию геометрии столкновений. Например, куб имеет 36 точек (6 сторон, 2 треугольника каждый, 3 точки для каждого треугольника). И алгоритм из первого сообщения дал плохие результаты для куба. Примеры точек для куба: http://nopaste.dk/download/3382 (должен возвращать ось идентичности)

Ответы

Ответ 1

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

Возможно, если вы заранее знаете, что объектом является, например, куб, вы можете использовать специализированный метод и использовать PCA для всего остального.

С другой стороны, если вы хотите вычислить истинный OBB, существуют существующие реализации, которые вы можете использовать, например. http://www.geometrictools.com/LibMathematics/Containment/Containment.html (в частности http://www.geometrictools.com/LibMathematics/Containment/Wm5ContMinBox3.cpp). Я считаю, что это реализует алгоритм, на который ссылается в комментариях к вашему вопросу.

Цитата из этой страницы:

Файлы ContMinBox3 реализуют алгоритм вычисления поле с минимальным объемом, содержащее точки. Этот метод вычисляет выпуклая оболочка точек, выпуклая многогранник. Блок минимального объема либо имеет грань, совпадающую с гранью выпуклого многогранника или имеет оси, заданные тремя взаимно перпендикулярные края выпуклый многогранник. Каждая грань выпуклый многогранник обрабатывается проектирование многогранника на плоскость лица, вычисляя прямоугольник минимальной площади, содержащий проекций и вычислений минимальный интервал, содержащий проекции на перпендикуляр лицо. Прямоугольник минимальной площади и минимальный интервал сформировать поле кандидата. Затем все троек ребер выпуклого многогранника обработанный. Если какая-либо тройка взаимно перпендикулярные края, самый маленький ящик с осями в направлениях ребра вычисляются. Из всех этих ящиков, один с наименьшим объемом поле минимального объема, содержащее оригинальный пункт комплект.

Если, как вы говорите, ваши объекты не имеют большого количества вершин, время выполнения должно быть приемлемым.

В обсуждении на http://www.gamedev.net/topic/320675-how-to-create-oriented-bounding-box/ автор вышеупомянутой библиотеки проливает больше света на тему:

Подход Gottschalk к построению OBB заключается в вычислении ковариационной матрицы для множества точек. Собственными векторами этой матрицы являются оси OBB. Среднее значение баллов - центр OBB. OBB не гарантированно имеет минимальный объем всех содержащих ящиков. Дерево OBB создается путем рекурсивного разбиения треугольной сетки, вершины которой являются точками. Для расщепления упоминается пара эвристик.

Шкала минимального объема (MVB), содержащая набор точек, представляет собой поле минимального объема, содержащее выпуклую оболочку точек. Корпус представляет собой выпуклый многогранник. Основываясь на результате Джо О'Рурка, MVB поддерживается гранью многогранника или тремя перпендикулярными краями многогранника. "Поддерживается лицом" означает, что MVB имеет грань, совпадающую с гранью многогранника. "Поддерживается тремя перпендикулярными краями" означает, что три перпендикулярных края MVB совпадают с краями многогранника.

Как указывает jyk, реализации любого из этих алгоритмов не являются тривиальными. Тем не менее, никогда не позволяйте этому препятствовать вам попробовать:) AABB может быть хорошей подгонкой, но он также может быть очень плохим. Рассмотрим "тонкий" цилиндр с конечными точками в (0,0,0) и (1,1,1) [представьте, что цилиндр является отрезком линии, соединяющим точки]. AABB равен 0 <= x <= 1, 0 <= y <= 1 и 0 <= z <= 1, с объемом 1. MVB имеет центр (1,1,1 )/2, ось (1,1,1)/sqrt (3) и степень для этой оси sqrt (3)/2. Он также имеет две дополнительные оси, перпендикулярные первой оси, но экстенты - 0. Объем этого блока равен 0. Если вы придаете линейному сегменту небольшую толщину, MVB становится немного больше, но по-прежнему имеет объем, намного меньший, чем ААББ.

Какой тип выбранного вами окна зависит от ваших собственных данных приложения.

Реализации всего этого на моем сайте www.geometrictools.com. Я использую эвристику медианного разделения для деревьев с ограниченным объемом. Конструкция MVB требует выдувного искателя корпуса в 2D, выдувного искателя корпуса в 3D и метода вычисления минимальной площади, содержащей набор плоских точек. Для этого я использую для этого вращающийся суппорт.

Ответ 2

Сначала вы должны вычислить центроид точек, в псевдокоде

mu = sum(0..N, x[i]) / N

тогда вам нужно вычислить матрицу ковариации

C = sum(0..N, mult(x[i]-mu, transpose(x[i]-mu)));

Обратите внимание, что mult выполняет (3x1) матричное умножение на (1x3) умножение матрицы, а результат представляет собой матрицу 3x3.

Собственные векторы матрицы C определяют три оси OBB.

Ответ 3

В С++ в сети появилась новая библиотека ApproxMVBB, которая вычисляет приближение для ограничивающего блока минимального объема. Он выпущен под лицензиями MPL 2.0 и написан мной.

Если у вас есть время посмотреть: http://gabyx.github.io/ApproxMVBB/

Библиотека совместима с С++ 11 и требует только Eigen http://eigen.tuxfamily.org. Тесты показывают, что аппроксимация для 140 миллионов точек в 3D может быть рассчитана в разумные сроки (около 5-7 секунд) в зависимости от ваших настроек для приближения.