2011-05-21 2 views
2

Мне удалось рассчитать радиус ограниченной сферы двумя способами, но никто не дает мне именно то, что я хочу. Мне не нужна «пиксельная» идеальная ограничивающая сфера, но мне бы хотелось что-то лучшее, чем то, что у меня есть сейчас.Имея небольшой вопрос, вычисляющий радиус ограниченной сферы

Я использую модели Wavefront .obj и вычисляю радиус ограниченной сферы для этих моделей. Я извлекаю текущие размеры модели (я использую библиотеку GLM от Nate Robbins), которая даст мне измерение на каждой оси.

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

Второй подход: Разделите каждую ось на 2, и это даст мне радиус на каждой оси. Затем я делаю это, чтобы вынуть радиус для ограничивающей сферы:

r = SQRT(x*x + y*y + z*z) 

Но это дает мне довольно большой радиус. Объект будет полностью закрыт в сфере, но сфера довольно большая, больше, чем должно быть.

Я не понимаю, что я делаю неправильно в формуле выше, насколько я знаю, она должна работать. Но я, очевидно, ошибаюсь ...

+0

Для куба или поля вашего второй подход дает вам точный радиус ограничивающей сферы. Таким образом, нет лучшего подхода, использующего только размерные экстенты на ось. – Howard

ответ

4

Ваш второй подход должен дать вам ограничивающий шар для вашей ограничивающей рамки, но, как вы обнаружили, он будет больше, чем необходимо для чего-либо другого, кроме коробки.

Лучше ограничивающая сферу можно найти перевод точек модели таким образом, они сосредоточены на нуле, используя размеры ограничительной рамки у вас уже есть, то для каждая отдельная вершина вычислить радиус от начала координат для этой точки, используя формулу sqrt(x*x + y*y + z*z). Какой из них самый большой - это радиус вашей ограниченной сферы.

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

Чтобы показать это в 2D, красный контур является ограничивающим прямоугольником формы, а синий круг - ограничивающим кругом коробки. Улучшенный круг с использованием вершин многоугольника и центрированный на нем зеленый. Обратите внимание, что ни одна из точек черного полигона не касается синего круга.

polygon (black), bounding box (red), bounding circle of the poly (green), bounding circle of the box (blue)

+0

Я понимаю, что это будет больше, чем необходимо, но не должно, по крайней мере, одна точка объекта «коснуться» сферы где-нибудь? Потому что ни один из них «не касается», все они уходят, и я понимаю, почему ... –

+0

Например, давайте подумаем в 2D. Если у меня есть прямоугольник 4x2, радиус будет 'SQRT (2 * 2 + 1 * 1)'. При рисовании круга внутри прямоугольника углы прямоугольника касаются круга. Разве это не должно быть то же самое в 3D? –

0

Если это шар, то разве вам не нужно работать только на одной оси? Я мог бы быть здесь, но по определению, не будет ли сфера иметь такую ​​же ширину, высоту и глубину? Итак, радиус на одной оси = радиус на другом = радиус другого?

+0

Конечно, я никогда не говорил иначе. –

+0

Тогда зачем использовать sqrt (x * x + y * y + z * z), когда вы могли бы просто использовать 0.5 * x? Возможно, я что-то пропустил. –

+0

Поскольку x! = Y! = Z. Или они могут быть равны, зависит от объекта. Мне нужны все оси, потому что объект может быть действительно высоким и тонким, например. И поэтому мне нужно использовать теорему Пифагора. Возможно, я тот что-то не хватает, но так я вижу. –

1

Один простой способ будет использовать Miniball, чтобы вычислить точную ограничивающую сферу модели. Интеграция его в ваш проект без проблем, поскольку он состоит только из одного заголовка. Однако он лицензируется под GPL, что может быть проблемой.Пример:

#include "Miniball.h" 

// ... 

Miniball<3> boundingSphere; 

// Iterate over all vertices in the model 
for (int vertexId = 0; vertexId < model.getNumVertices(); ++vertexId) { 
    // Convert vertex position to Miniball point type 
    Point<3> point; 
    for (int dim = 0; dim < 3; ++dim) { 
    point[dim] = model.getVertex(vertexId)[dim]; 
    } 
    // Add point to bounding sphere 
    boundingSphere.check_in(point); 
} 
// Actually calculate the sphere 
boundingSphere.build(); 

// Get back the results 
Point<3> center = boundingSphere.center(); 
double radiusSq = boundingSphere.squared_radius(); 
+0

Спасибо, но я хочу, чтобы не использовать больше «библиотек», и на самом деле не имеет особого значения, что у меня есть точная ограничивающая сфера. Я просто хочу понять, почему мои вычисления в первую очередь терпят неудачу (или то, что я не понимаю). –

+0

@Nazgulled: это известная задача геометрического вычисления с известным решением. См. Статью [Bounding sphere problem] в Википедии (http://en.wikipedia.org/wiki/Bounding_sphere). – rwong

+0

Вот еще одна библиотека для вычисления мини-билета, доступная под лицензией Apache: http://github.com/hbf/miniball – Hbf

Смежные вопросы