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.

model::point

model::d2::point_xy

model::linestring

model::polygon

model::multi_point

model::multi_linestring

model::multi_polygon

model::box

model::ring

model::segment

model::referring_segment

 

model::point

Basic point class, having coordinates defined in a neutral way.

Description

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.

model::d2::point_xy

2D point in Cartesian coordinate system

 

model::linestring

A linestring (named so by OGC) is a collection (default a vector) of points.

 

model::polygon

The polygon contains an outer ring and zero or more inner rings.

 

2、常见算法

提供的算法有:面积、长度、周长、质心、凸壳、交集(剪裁)、内(多边形中的点)、距离、包络线(边界框)、简化、变换等。

area

assign

append

buffer

centroid

clear

convert

convex_hull

correct

covered_by

crosses

densify

difference

discrete_frechet_distance

discrete_hausdorff_distance

disjoint

distance

envelope

equals

expand

for_each

intersection

intersects

is_empty

is_simple

is_valid

length

make

num_geometries

num_interior_rings

num_points

num_segments

overlaps

perimeter

relate

relation

reverse

simplify

sym_difference

touches

transform

union_

unique

within

常见的有以下几种:

计算面积

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、几何图形的算术运算

add_point

add_value

assign_point

assign_value

cross_product

cross_product

divide_point

divide_value

dot_product

multiply_point

multiply_value

subtract_point

subtract_value

 

6、官方示例

https://www.boost.org/doc/libs/1_69_0/libs/geometry/doc/html/geometry/spatial_indexes/rtree_examples/index_of_polygons_stored_in_vector.html

 

#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;

}

### Boost.Geometry库简介 Boost.Geometry是一个功能强大的C++模板库,专门设计用于执行几何计算和操作。该库提供了一系列的数据结构与算法,支持多种几何类型的操作,包括但不限于点、线段、多边形等。 #### 主要特性 - 支持二维及三维几何对象的创建与操作 - 提供丰富的几何运算函数,如交集检测、距离测量等 - 可扩展性强,允许用户定义自己的几何类型并集成到现有框架中 ### 创建Point对象实例 为了展示`boost::geometry::model::point`的实际应用,下面给出了一段简单的测试程序[^1]: ```cpp #include <iostream> #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> int main() { typedef boost::geometry::model::d2::point_xy<double> point_type; // 定义两点A(0, 0), B(3, 4) point_type a(0, 0); point_type b(3, 4); double distance = boost::geometry::distance(a, b); std::cout << "Distance between A and B is: " << distance << "\n"; } ``` 此代码片段展示了如何利用`boost::geometry::model::point`来表示坐标系内的位置,并通过内置的距离计算方法求解两者的欧几里得距离。 ### 判断几何图形是否相交 对于需要验证两个几何实体是否存在重叠区域的情况,可以借助于`intersects()`函数实现这一目的[^2]: ```cpp #include <boost/geometry.hpp> #include <boost/geometry/geometries/polygon.hpp> #include <boost/geometry/geometries/adapted/c_array.hpp> BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) namespace bg = boost::geometry; typedef bg::model::polygon<bg::model::d2::point_xy<int>> polygon_type; bool checkIntersection(const polygon_type& poly1, const polygon_type& poly2){ return bg::intersects(poly1,poly2); } // 测试用例... ``` 上述例子说明了怎样构建一个多边形模型以及调用`intersects()`来进行交叉性检验的过程。 ### 自定义多边形处理 当涉及到更复杂的场景时,比如绘制不规则形状或多部件组合而成的地图边界,则可能需要用到更加灵活的方式去描述这些特殊形态的对象。这里有一个关于自定义多边形的例子[^3]: ```cpp #include <vector> #include <boost/geometry.hpp> #include <boost/geometry/geometries/register/multi_polygon.hpp> #include <boost/geometry/geometries/multi_polygon.hpp> using namespace boost::geometry; using PointType = model::d2::point_xy<double>; using PolygonType = model::polygon<PointType>; using MultiPolygonType = model::multi_polygon<PolygonType>; void createCustomPolygons(MultiPolygonType &mpolys) { // 添加第一个简单矩形作为单个多边形的一部分... mpolys.push_back(PolygonType()); append(mpolys.back().outer(), {PointType(0 ,0 ), PointType(5 ,0 ), PointType(5 ,5 ), PointType(0 ,5 )}); // 继续添加其他部分直至完成整个复合体... } ``` 这段源码揭示了如何注册新的几何类别并通过向量容器管理多个独立但关联紧密的空间单元的方法论。 ### 验证几何对象间的关系——Disjoint判定 最后,在某些情况下我们还需要确认给定的一对几何要素之间没有任何公共部分;这时就可以运用`disjoint()`函数快速得出结论[^4]: ```cpp template<typename Geometry1, typename Geometry2> bool areGeometriesDisjoint(Geometry1&& geom1, Geometry2&& geom2){ return !bg::intersects(geom1, geom2); } // 或者直接使用 disjoint 函数: if(bg::disjoint(polygon_a, polygon_b)){ // 如果返回true则代表两者互斥无接触 } ``` 以上就是有关Boost.Geometry的一些基础概念及其典型应用场景介绍。希望这能帮助读者更好地理解和掌握这个优秀的开源工具包!
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oceanstonetree

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值