天天看点

boost源码学习之gemotry3:快速入门

boost gemotry

3.快速入门

这个快速入门展示了Boost.Geometry的一些特性,以带注释的相对简单的代码段的形式。

下面的代码假设包含了boost/geometry.hpp,和使用了头文件boost::geometry。Boost.Geometry是尽头文件的,因此只包含头文件就可以了。没有必要与任何库链接。

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

using namespace boost::geometry;
           

3.1笛卡尔

可以只使用库的一小部分。例如:两点之间的距离是一个常见的用例。促进几何体可以从各种类型计算它。使用它自己的类型之一:

model::d2::point_xy<int> p1(1, 1), p2(2, 2);
std::cout << "Distance p1-p2 is: " << distance(p1, p2) << std::endl;
           

如果包含右标题,并且类型绑定到坐标系,则可以使用其他各种类型作为点:普通C数组、Boost数组,Boost Tuple’s,Boost.Fusion,导入的结构,你自己的类。。。

注册和使用C数组:

#include <boost/geometry/geometries/adapted/c_array.hpp>

BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
           
int a[2] = {1,1};
int b[2] = {2,3};
double d = distance(a, b);
std::cout << "Distance a-b is: " << d << std::endl;
           

另一个常用的算法是point-in-polygon,在Boost.Geomety中由within函数实现。我们在这里显示他的用法,检查一个Boost.Tuple(作为一个点)是否位于多边形中,该多边形由C数组点对填充。

但是首先要注册一个Boost.Tuple,如同注册C数组一样:

#include <boost/geometry/geometries/adapted/boost_tuple.hpp>

BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
           
double points[][2] = {{2.0, 1.3}, {4.1, 3.0}, {5.3, 2.6}, {2.9, 0.7}, {2.0, 1.3}};
model::polygon<model::d2::point_xy<double> > poly;
append(poly, points);
boost::tuple<double, double> p = boost::make_tuple(3.7, 2.0);
std::cout << "Point p is in polygon? " << std::boolalpha << within(p, poly) << std::endl;
           

我们可以计算一个多边形的面积:

根据模板库的性质,可以混合点类型。我们再次计算距离,现在使用一个C数组点和一个Boost元组点:

double d2 = distance(a, p);
std::cout << "Distance a-p is: " << d2 << std::endl;
           

上面列举的代码段产生如下输出:

Distance p1-p2 is: 1.41421
Distance a-b is: 2.23607
Point p is in polygon? true
Area: 3.015
Distance a-p is: 2.87924
           

3.2非笛卡尔

也可以使用非笛卡尔点。例如:球体上的点。当使用诸如距离之类的算法时,库“检查”它是否在处理球形点,并计算球体上的距离,而不是应用毕达哥拉斯定理。

促进几何体支持地理坐标系,但该坐标系位于扩展中,且未在当前的Boost版本中发布。

我们将地球近似为一个球体,并计算阿姆斯特丹和巴黎之间的距离:

typedef boost::geometry::model::point
    <
        double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::degree>
    > spherical_point;

spherical_point amsterdam(4.90, 52.37);
spherical_point paris(2.35, 48.86);

double const earth_radius = 3959; // miles
std::cout << "Distance in miles: " << distance(amsterdam, paris) * earth_radius << std::endl;
           

3.3适应结构

最后是一个完全不同领域的示例:开发基于窗口的应用程序,例如使用QtWidgets。只要Qt类在Boost中注册。我们可以使用它们。例如,我们可以检查两个矩形是否重叠,如果重叠,则将第二个矩形移动到另一个位置:

QRect r1(100, 200, 15, 15);
QRect r2(110, 210, 20, 20);
if (overlaps(r1, r2))
{
    assign_values(r2, 200, 300, 220, 320);
}
           
如何在Boost中注册QT类

3.4更多

在参考(reference)部分可以找到更多的例子。