В настоящее время я использую библиотеку надстройки геометрии / пространственного индекса для выполнения запросов диапазона на трехмерных ограничивающих прямоугольниках. Например, я могу получить список всех ограничивающих рамок, которые перекрывают ограничивающую рамку запроса.
Документация (http://www.boost.org/doc/libs/1_54_0_beta1/libs/geometry/doc/html/geometry/spatial_indexes/queries.html) показывает, что — по крайней мере в 2d — полигоны можно использовать вместо ограничивающего прямоугольника в качестве объекта запроса. Можно ли использовать более сложные формы запросов в 3D? Я имею в виду такие объекты, как ориентированные ограничивающие рамки, пирамиды или камеры. Если так: как я могу это сделать / где я могу найти пример для этого?
Спасибо
Вкратце: это не поддерживается, потому что в настоящее время в Boost.Geometry OOB, концепции Pyramid и Frustum недоступны / не поддерживаются.
Но, теоретически, должна быть возможность выполнить такой запрос. Во время запроса bgi::rtree
вызывает адекватный логический алгоритм, определенный в boost::geometry
пространство имен, например если ты позвонишь
rtree.query(bgi::intersects(my_geometry), out_it);
внутренне
bg::intersects(xxx, my_geometry);
называется, где xxx
является ограничительной рамкой узла или индексируемым значением (геометрия извлекается из ValueType
передается пользователем в bgi::rtree
например, также коробка или точка). Так что, если вы реализовали, например,
namespace boost { namespace geometry {
template <typename Box> inline
bool intersects(Box const& b, MyFrustum const& f)
{
// your implementation
}
}}
теоретически это должно работать. Не проверял это все же.
Выше:
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
Также, если вы хотите связаться с разработчиками напрямую, вы можете подписаться на список рассылки Boost.Geometry: http://lists.boost.org/mailman/listinfo.cgi/geometry
У меня были те же проблемы, и после разговора с @Adam он предложил следующее решение, которое устранило проблему для меня (я строю свой код на GCC, и решение, приведенное выше, похоже, компилируется только на Visual Studio).
#include <boost/geometry.hpp>
struct MyFrustum
{
MyFrustum(int d) : dummy(d) {}
int dummy;
};
namespace boost { namespace geometry {
// This will be called for Nodes and Values!
template <typename Box> inline
bool intersects(Box const& b, MyFrustum const& f)
{
std::cout << "checking the intersection with " << f.dummy << std::endl;
return true;
}
}}
#include <boost/geometry/index/rtree.hpp>
Очевидно, порядок, в котором определяются вещи, важен, чтобы компилятор не отступал от своей реализации по умолчанию (которая выдает еще не реализованные ошибки).
Надеюсь, что это помогает, и снова, спасибо Адаму!
Другие ответы здесь великолепны, но я все еще сталкивался с проблемами в XCode, независимо от того, в каком порядке я включал / объявлял вещи. Я публикую этот ответ для тех, кто не может заставить его работать в своей среде.
Другие решения здесь хорошо работали для меня в Visual Studio 2013, но не в Xcode 5.1.1. Кажется, есть проблема разрешения перегрузки в этом компиляторе. Решение состоит в том, чтобы избежать использования типа шаблона для «Box» и использовать все конкретные типы напрямую, например так:
#include <boost/geometry.hpp>
namespace bg = boost::geometry;
using point3d = bg::model::point<float, 3, bg::cs::cartesian>;
using box3d = bg::model::box<point3d>;
namespace boost { namespace geometry {
template <> inline
bool intersects(box3d const& b, MyFrustum const& p) {
// your implementation
return true;
}
}