- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试了解如何实现 R 树,它将用于“选择”边界矩形中包含的一组几何对象。我检查了 article在维基百科上,它以 B-Tree 显示了数据布局的示例.
我可以写一个 B-Tree 并用它来写一个 R-Tree,但这是两个复杂的数据结构,我必须调试、测试等。我宁愿重用一个现有的树实现(std::set/multiset)并提供排序操作。
假设我的形状有以下界面:
class Shape
{
public:
Shape();
virtual ~Shape();
const AABB & bounding_box() const = 0;
};
并提供这个仿函数来排序形状:
struct OrderShapes
{
bool operator()(Shape * const & left, Shape * const & right) const
{
return right->bounding_box().contains(left->bounding_box());
}
};
会 std::set<Shape *, OrderShapes>
表现得像一个有效的 R 树?如果没有,我如何在不重新发明轮子的情况下解决这个问题?
最佳答案
您还可以使用 Boost.Geometry 库:
http://www.boost.org/doc/libs/release/libs/geometry/doc/html/index.html
如果您想使用自己的 Point 和 AABB 类型,您应该使它们适应 Point 和 Box 概念,以便告诉 Boost.Geometry 库如何处理这些类型。例如。请参阅以下页面:
否则你可以使用预定义的。
假设您想在 rtree 中存储指针(我将使用 boost::shared_ptr),代码可能如下所示:
#include <boost/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/foreach.hpp>
#include <vector>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
namespace bgm = boost::geometry::model;
/* The registration of your Point and Box types goes here */
// OR use predefined ones
typedef bgm::point<float, 2, bg::cs::cartesian> Point;
typedef bgm::box<Point> AABB;
class Shape
{
public:
Shape() {}
virtual ~Shape() {}
const AABB & bounding_box() const { return m_aabb; }
private:
AABB m_aabb;
};
// Tell the rtree how to extract the AABB from the Shape
namespace boost { namespace geometry { namespace index {
template <>
struct indexable< boost::shared_ptr<Shape> >
{
typedef boost::shared_ptr<Shape> V;
typedef AABB const& result_type;
result_type operator()(V const& v) const { return v->bounding_box(); }
};
}}} // namespace boost::geometry::index
int main()
{
// The rtree
bgi::rtree< boost::shared_ptr<Shape>, bgi::rstar<32> > rt;
// Store some shapes
rt.insert(boost::shared_ptr<Shape>(new Shape()));
rt.insert(boost::shared_ptr<Shape>(new Shape()));
rt.insert(boost::shared_ptr<Shape>(new Shape()));
/*...*/
// Search for some shapes
std::vector<boost::shared_ptr<Shape> > query_result;
rt.query(bgi::intersects(AABB(/*...*/)), std::back_inserter(query_result));
BOOST_FOREACH(boost::shared_ptr<Shape> & s, query_result)
{
/* Do something with each shape */
/* but don't modify the AABB if the Shape is stored in the rtree! */
}
// Remove them from the rtree
BOOST_FOREACH(boost::shared_ptr<Shape> & s, query_result)
{
rt.remove(s);
}
return 0;
}
请记住,因为 AABB 是 Shape 的属性并且我们正在存储指针,所以可以从 rtree 空间索引的外部修改 AABB。当值存储在索引或容器中时,您不应修改用作键的数据。
如果您不想将 AABB 存储在 Shape 中或/和提高 rtree 安全性,您可以存储例如std::pair
// The value type
typedef std::pair<AABB, boost::shared_ptr<Shape> > MyVal;
// The rtree
bgi::rtree<MyVal, bgi::rstar<32> > rt;
// Store a shape
boost::shared_ptr<Shape> s(new Shape());
rt.insert(std::make_pair(s->calculate_aabb(), s));
/* The rest of the code */
关于c++ - R-树 : should I reinvent the wheel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14195111/
好的,公平的警告:这是我的 ridiculous question 的后续行动从上周开始。虽然我认为这个问题并不那么荒谬。无论如何,这里是: 上一个荒谬的问题: 假设我有一些基本特征 T带有子类 A
我正在尝试创建一个实用程序类,它将能够处理可运行程序包并以不同的组合(同步、异步)执行它们。 例如:想象这是一个类似 json 的复合任务表示。 “[]”保持异步任务,“{}”保持同步任务。 [
我正在尝试了解如何实现 R 树,它将用于“选择”边界矩形中包含的一组几何对象。我检查了 article在维基百科上,它以 B-Tree 显示了数据布局的示例. 我可以写一个 B-Tree 并用它来写一
我正在为一个项目制作 IVR 系统,并决定使用 Twilio处理电话部分(调用和接听电话,发送和接收短信)。这将显示一个带有 IVR 前端的网站,允许用户使用他们的按键式电话浏览该网站。 我并没有让所
我需要在一台机器上实现非常快速、低延迟、高吞吐量的进程间(或应用程序域间)通信。 消息通常每隔几毫秒就会流动一次(但在几分钟内,每毫秒甚至可能有多达 3-5 条消息),每条消息的大小不到 1KB,目标
我是一名优秀的程序员,十分优秀!