Boost.Geometry介绍
最在项目中要用到计算几何的东西,计算三维空间中面片与六面体的相交判断,通过各种搜索发现boost库中的Geometry模块还不错,可以比较容易地实现。这里记录一下这个库的基本情况。
1、常见几何对象
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/multi_point.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/multi_linestring.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/geometries/variant.hpp>
Boost.Geometry的model有point_xy, point, multi_point, ,segment,linestring,multi_linestring, box,ring,polygon,multi_polygon, variant.
Basic point class, having coordinates defined in a neutral way.
Defines a neutral point class, fulfilling the Point Concept. Library users can use this point class, or use their own point classes. This point class is used in most of the samples and tests of Boost.Geometry This point class is used occasionally within the library, where a temporary point class is necessary.
2D point in Cartesian coordinate system
A linestring (named so by OGC) is a collection (default a vector) of points.
The polygon contains an outer ring and zero or more inner rings.
2、常见算法
提供的算法有:面积、长度、周长、质心、凸壳、交集(剪裁)、内(多边形中的点)、距离、包络线(边界框)、简化、变换等。
常见的有以下几种:
计算面积
Boost::Geometry::area(obj1)
计算距离
Boost::Geometry::distance(obj1, obj2)
判断是否相交
Boost::Geometry::intersects(obj1, obj2)
计算交点
Boost::Geometry::intersection(obj1, obj2, result)
判断是否在box内
Boost::Geometry::within(obj1, obj2)
3、boost.Geometry可以与VS的GraphicalDebugging插件可以配合使用,查看几何图形。
在调试过程中插入断点,通过在GraphicalDebugging界面输入对象的名字就可以查看几何对象的形态。在视图中的其他窗口可以找到刚刚安装的插件的窗口,Geometry Watch,Graphical Watch,Plot Watch。
4、几何图形的输入输出
DSV (Delimiter-Separated Values)
WKT (Well-Known Text)
SVG (Scalable Vector Graphics)
前两种是文本格式数据流,第三种是图形化输入和输出。
5、几何图形的算术运算
6、官方示例
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <cmath>
#include <vector>
#include <iostream>
#include <boost/foreach.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
int main()
{
typedef bg::model::point<float, 2, bg::cs::cartesian> point; //define point 2 dimension
typedef bg::model::box<point> box;
typedef bg::model::polygon<point, false, false> polygon; // ccw, open polygon
typedef std::pair<box, unsigned> value;
// polygons
std::vector<polygon> polygons;
// create some polygons
for ( unsigned i = 0 ; i < 10 ; ++i )
{
// create a polygon
polygon p;
for ( float a = 0 ; a < 6.28316f ; a += 1.04720f )
{
float x = i + int(10*::cos(a))*0.1f;
float y = i + int(10*::sin(a))*0.1f;
p.outer().push_back(point(x, y));
}
// add polygon
polygons.push_back(p);
}
// display polygons
std::cout << "generated polygons:" << std::endl;
BOOST_FOREACH(polygon const& p, polygons)
std::cout << bg::wkt<polygon>(p) << std::endl;
// create the rtree using default constructor
bgi::rtree< value, bgi::rstar<16, 4> > rtree;
// fill the spatial index
for ( unsigned i = 0 ; i < polygons.size() ; ++i )
{
// calculate polygon bounding box
box b = bg::return_envelope<box>(polygons[i]);
// insert new value
rtree.insert(std::make_pair(b, i));
}
// find values intersecting some area defined by a box
box query_box(point(0, 0), point(5, 5));
std::vector<value> result_s;
rtree.query(bgi::intersects(query_box), std::back_inserter(result_s));
// find 5 nearest values to a point
std::vector<value> result_n;
rtree.query(bgi::nearest(point(0, 0), 5), std::back_inserter(result_n));
// note: in Boost.Geometry the WKT representation of a box is polygon
// note: the values store the bounding boxes of polygons
// the polygons aren't used for querying but are printed
// display results
std::cout << "spatial query box:" << std::endl;
std::cout << bg::wkt<box>(query_box) << std::endl;
std::cout << "spatial query result:" << std::endl;
BOOST_FOREACH(value const& v, result_s)
std::cout << bg::wkt<polygon>(polygons[v.second]) << std::endl;
std::cout << "knn query point:" << std::endl;
std::cout << bg::wkt<point>(point(0, 0)) << std::endl;
std::cout << "knn query result:" << std::endl;
BOOST_FOREACH(value const& v, result_n)
std::cout << bg::wkt<polygon>(polygons[v.second]) << std::endl;
return 0;
}