#include <boost/assign.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/geometries/polygon.hpp> #include <boost/geometry/algorithms/transform.hpp>
#include <boost/geometry/strategies/transform/inverse_transformer.hpp>
#include <boost/geometry/strategies/transform/matrix_transformers.hpp> namespace bg = boost::geometry;
typedef bg::model::d2::point_xy<double> DPoint;
typedef bg::model::segment<DPoint> DSegment;
typedef bg::model::linestring<DPoint> DLineString;
typedef bg::model::box<DPoint> DBox;
typedef bg::model::ring<DPoint, false> DRing;
typedef bg::model::polygon<DPoint, false> DPolygon;
//对Geometry库一些函数进行了封装,更加方便使用,包括(平移,旋转,缩放,求点到直线的垂足,通过比例求段上的点等等)
namespace GeometryExtend
{
DPoint operator +(const DPoint& pt1, const DPoint& pt2)
{
DPoint pt(pt1);
bg::add_point(pt, pt2);
return pt;
} const DPoint& operator +=(DPoint& pt1, const DPoint& pt2)
{
bg::add_point(pt1, pt2);
return pt1;
} DPoint operator -(const DPoint& pt1, const DPoint& pt2)
{
DPoint pt(pt1);
bg::subtract_point(pt, pt2);
return pt;
} const DPoint& operator -=(DPoint& pt1, const DPoint& pt2)
{
bg::subtract_point(pt1, pt2);
return pt1;
} //////////////////////////////////////////////////////////////////////////
// 平移变换
//////////////////////////////////////////////////////////////////////////
template<typename Geometry, typename CalculationType>
struct translate_impl
{
static void apply(Geometry& geometry, const CalculationType& x, const CalculationType& y)
{
bg::strategy::transform::translate_transformer<CalculationType, 2, 2> t(x, y);
bg::transform(geometry, geometry, t);
}
}; template<typename Geometry, typename CalculationType>
struct translate_trais
{
static void apply(Geometry& geometry, const CalculationType& x, const CalculationType& y);
}; #define TRANSLATE_TRAIS(Geometry) \
template<typename CalculationType> \
struct translate_trais<Geometry, CalculationType> \
{ \
static void apply(Geometry& geometry, const CalculationType& x, const CalculationType& y) \
{ \
translate_impl<Geometry, CalculationType>::apply(geometry, x, y); \
} \
}; TRANSLATE_TRAIS(DPoint)
TRANSLATE_TRAIS(DSegment)
TRANSLATE_TRAIS(DBox)
TRANSLATE_TRAIS(DRing)
TRANSLATE_TRAIS(DPolygon) template<typename Geometry, typename CalculationType>
void translate(Geometry& geometry, const CalculationType& x, const CalculationType& y)
{
translate_trais<Geometry, CalculationType>::apply(geometry, x, y);
} //////////////////////////////////////////////////////////////////////////
// 旋转变换
//////////////////////////////////////////////////////////////////////////
template<typename Geometry, typename DegreeOrRadian, typename CalculationType>
struct rotate_impl
{
static void apply(Geometry& geometry, const CalculationType& angle)
{
bg::strategy::transform::rotate_transformer<DegreeOrRadian, CalculationType, 2, 2> t(angle);
bg::transform(geometry, geometry, t);
}
}; template<typename Geometry, typename DegreeOrRadian, typename CalculationType>
struct rotate_trais
{
static void apply(Geometry& geometry, const CalculationType& angle);
}; #define ROTATE_TRAIS(Geometry, DegreeOrRadian) \
template<typename CalculationType> \
struct rotate_trais<Geometry, DegreeOrRadian, CalculationType> \
{ \
static void apply(Geometry& geometry, const CalculationType& angle) \
{ \
rotate_impl<Geometry, DegreeOrRadian, CalculationType>::apply(geometry, angle); \
} \
}; ROTATE_TRAIS(DPoint, bg::degree)
ROTATE_TRAIS(DPoint, bg::radian)
ROTATE_TRAIS(DSegment, bg::degree)
ROTATE_TRAIS(DSegment, bg::radian)
ROTATE_TRAIS(DBox, bg::degree)
ROTATE_TRAIS(DBox, bg::radian)
ROTATE_TRAIS(DRing, bg::degree)
ROTATE_TRAIS(DRing, bg::radian)
ROTATE_TRAIS(DPolygon, bg::degree)
ROTATE_TRAIS(DPolygon, bg::radian) template<typename Geometry, typename DegreeOrRadian, typename CalculationType>
void rotate(Geometry& geometry, const DegreeOrRadian&, const CalculationType& angle)
{
rotate_trais<Geometry, DegreeOrRadian, CalculationType>::apply(geometry, angle);
} template<typename Geometry, typename Point, typename DegreeOrRadian, typename CalculationType>
void point_rotate(Geometry& geometry, const Point& point, const DegreeOrRadian& type, const CalculationType& angle)
{
Point pt(0, 0); bg::subtract_point(pt, point);
translate(geometry, bg::get<0>(pt), bg::get<1>(pt));
rotate(geometry, type, angle);
translate(geometry, bg::get<0>(point), bg::get<1>(point));
} //////////////////////////////////////////////////////////////////////////
// 比例变形
//////////////////////////////////////////////////////////////////////////
template<typename Geometry, typename CalculationType>
struct scale_impl
{
static void apply(Geometry& geometry, const CalculationType& scale_x, const CalculationType& scale_y)
{
bg::strategy::transform::scale_transformer<CalculationType, 2, 2> t(scale_x, scale_y);
bg::transform(geometry, geometry, t);
}
}; template<typename Geometry, typename CalculationType>
struct scale_trais
{
static void apply(Geometry& geometry, const CalculationType& scale_x, const CalculationType& scale_y);
}; #define SCALE_TRAIS(Geometry) \
template<typename CalculationType> \
struct scale_trais<Geometry, CalculationType> \
{ \
static void apply(Geometry& geometry, const CalculationType& scale_x, const CalculationType& scale_y) \
{ \
scale_impl<Geometry, CalculationType>::apply(geometry, scale_x, scale_y); \
} \
}; SCALE_TRAIS(DPoint)
SCALE_TRAIS(DSegment)
SCALE_TRAIS(DBox)
SCALE_TRAIS(DRing)
SCALE_TRAIS(DPolygon) template<typename Geometry, typename CalculationType>
void scale(Geometry& geometry, const CalculationType& scale_x, const CalculationType& scale_y)
{
scale_trais<Geometry, CalculationType>::apply(geometry, scale_x, scale_y);
} //////////////////////////////////////////////////////////////////////////
// 函数功能:
// 扩充box
//////////////////////////////////////////////////////////////////////////
template<typename Geometry, typename CalculateType>
void InflateBox(Geometry& geometry, CalculateType const& cx, CalculateType const& cy)
{
typedef typename bg::point_type<Geometry>::type point_type;
point_type& ptMin = geometry.min_corner();
point_type& ptMax = geometry.max_corner(); ptMin.x(ptMin.x() - cx);
ptMin.y(ptMin.y() - cy);
ptMax.x(ptMax.x() + cx);
ptMax.y(ptMax.y() + cy);
} //////////////////////////////////////////////////////////////////////////
// 函数功能:
// 求点到线段的垂足;
// 返回值:
// true,垂足在线段上;
// false,垂足在线段外;
//////////////////////////////////////////////////////////////////////////
template<typename Point, typename Segment>
bool point_to_segment_org(Point const& point, Segment const& segment, Point& ptOut)
{
bool bInSegment = true; try
{
typedef typename bg::point_type<Segment>::type point_type;
point_type p[2] = {segment.first, segment.second}; if (boost::geometry::equals(point, p[0]) ||
boost::geometry::equals(point, p[1]))
{
boost::geometry::assign_point(ptOut, point);
bInSegment = true;
throw bInSegment;
} point_type v(p[1]), w(point); boost::geometry::subtract_point(v, p[0]);
boost::geometry::subtract_point(w, p[0]); typedef typename bg::select_calculation_type<Point, Segment, void>::type calculation_type; calculation_type const zero = calculation_type();
calculation_type const c1 = boost::geometry::dot_product(w, v);
if (c1 < zero)
{
bInSegment = false;
} double const c2 = boost::geometry::dot_product(v, v);
if (c2 < c1)
{
bInSegment = false;
} calculation_type const b = c1 / c2;
DPoint projected(p[0]); boost::geometry::multiply_value(v, b);
boost::geometry::add_point(projected, v);
boost::geometry::assign_point(ptOut, projected);
}
catch (bool)
{
} return bInSegment;
} //////////////////////////////////////////////////////////////////////////
// 函数功能:
// 通过比例求段上的点;
//////////////////////////////////////////////////////////////////////////
template<typename Segment, typename Point>
void get_segment_on_point_by_scale(Segment const& segment, double const& dScale, Point& ptOut)
{
typedef typename bg::point_type<Segment>::type point_type; point_type p[2] = {segment.first, segment.second};
point_type v(p[1]);
point_type ptDest(p[0]); boost::geometry::subtract_point(v, p[0]);
boost::geometry::multiply_value(v, dScale);
boost::geometry::add_point(ptDest, v);
boost::geometry::assign_point(ptOut, ptDest);
} //////////////////////////////////////////////////////////////////////////
// 函数功能:
// 通过长度求段上的点;
//////////////////////////////////////////////////////////////////////////
template<typename Segment, typename Point>
void get_segment_on_point_by_length(Segment const& segment, double const& dLength, Point& ptOut)
{
typedef typename bg::point_type<Segment>::type point_type; point_type p[2] = {segment.first, segment.second};
double dTotalLength = boost::geometry::distance(p[0], p[1]);
double dScale = dLength / dTotalLength; get_segment_on_point_by_scale(segment, dScale, ptOut);
}
}
 
 
int main()
{
DBox box1(DPoint(100, 100), DPoint(300, 200));
GeometryExtend::InflateBox(box1, 20, 10); DSegment sg1(DPoint(100, 100), DPoint(300, 300));
DPoint pt1(300, 100);
DPoint pt2(100, 0);
DPoint ptOut;
bool bOnSegment; bOnSegment = GeometryExtend::point_to_segment_org(pt1, sg1, ptOut);
bOnSegment = GeometryExtend::point_to_segment_org(pt2, sg1, ptOut); GeometryExtend::get_segment_on_point_by_scale(sg1, 0.5, ptOut);
GeometryExtend::get_segment_on_point_by_length(sg1, 0, ptOut); DPoint pt4;
DSegment sg4;
//平移变换
bg::assign_point(pt4, pt1);
GeometryExtend::translate(pt4, 10, 20);
bg::assign(sg4, sg1);
GeometryExtend::translate(sg4, 10, 20); //旋转变形
bg::assign(pt4, pt1);
GeometryExtend::rotate(pt4, bg::degree(), 45.0);
bg::assign(sg4, sg1);
GeometryExtend::rotate(sg4, bg::degree(), 45.0); //比例变换
bg::assign(pt4, pt1);
GeometryExtend::scale(pt4, 0.5, 0.2);
bg::assign(sg4, sg1);
GeometryExtend::scale(sg4, 0.5, 0.2); return 0;
}

boost库之geometry<二>的更多相关文章

  1. boost库之geometry

    环境:win732位旗舰版.VS2010旗舰版.boost 1.55.0版本.坐标系为MM_TEXT Geometry是一个开源的几何计算库,包含了几何图形最基本的操作(也支持复杂的操作),下面我们看 ...

  2. 【转】boost库之geometry

    #include <boost/assign.hpp> #include <boost/geometry/geometry.hpp> #include <boost/ge ...

  3. Boost 库Program Options--第二篇

    程式執行參數處理函式庫:Boost Program Options(2/N) 前一篇已經大致解釋了 Boost Program Options 基本上的使用方法.而這一篇,則來細講一下選項描述(opt ...

  4. (十二)boost库之多线程高级特性

    (十二)boost库之多线程高级特性 很多时候,线程不仅仅是执行一些耗时操作,可能我们还需要得到线程的返回值,一般的处理方法就是定义一个全局状态变量,不断轮训状态,就如我目前维护的一个项目,全局变量定 ...

  5. (二)boost库之字符串格式化

    (二)boost库之字符串格式化 程序中经常需要用到字符串格式化,就个人而言还是比较倾向于C格式的输出,如果只是打印日志,printf就够了,如果到生成字符串,获取你可以选择sprintf,但这些都是 ...

  6. C++ | boost库 类的序列化

    是的,这是今年的情人节,一篇还在研究怎么用的文章,文结的时候应该就用成功了. 恩,要有信心 神奇的分割线 不知何时装过boost库的header-only库, 所以ratslam中的boost是可以编 ...

  7. boost库学习之regex

    一.背景 项目中许多地方需要对字符串进行匹配,比如根据指定的过滤字符串来过滤文件名.刚开始是排斥使用boost库的,第一,我不熟悉boost库:第二,如果引入第三方库,就会增加库的依赖,这样的后果是, ...

  8. boost库学习之开篇

    本系列文章使用boost_1.58.0版本. 一.欢迎使用boost C++库 boost致力于提供一个免费的.便携的源代码级的库. 我们重视那些与C++标准一起工作良好的库.boost库将要成为一个 ...

  9. boost库在windows下的编译和使用

    因为跨平台的原因,现在要使用到boost库,boost库非常大,现在处于摸索阶段. 首先来说boost库在window下的安装和使用. 一.下载 首先从boost官方主页http://www.boos ...

随机推荐

  1. 6、Struts2拦截器实现权限控制

    1.创建如下项目结果 2.在com.entity包下创建 package com.entity; public class User { private String name; private St ...

  2. onSaveInstanceState()和onRestoreInstanceState()方法

    Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,它们不同于 onCreate().onPause()等生命周期方 ...

  3. awk 中 FS的用法

    在openwrt文件 ar71xx.sh中 查询设备类型时,有这么一句, machine=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {pr ...

  4. openwrt下关于snmpd的一些信息

    cd /tmp/ 上传: tftp -gr libnetsnmp_5.4.4-1_ar71xx.ipk 192.168.11.56 安装: opkg install libnetsnmp_5.4.4- ...

  5. OMCS ——卓尔不群的网络语音视频框架

    作为.NET平台上的开发人员,要开发出一个像样视频聊天系统或视频会议系统,非常艰难,这不仅仅是因为.NET对多媒体的支持比较有限,还因为网络语音视频这块涉及到了很多专业方面的技术,而.NET在这些方面 ...

  6. Java 字符串比较,String 中的一些方法 == 和 equals 的详解

    "==" 是比较的是两个对象的内存地址,而equals方法默认情况下是比较两个对象的内存地址. 1.String str = "hello"  生成的字符串,首 ...

  7. 表单提交是ajax提交,PC提交没问题但是手机提交就会一直跳到error,并且也没状态码一直是0

    真是被自己蠢死了button标签他会自动提交刷新页面 <form id="baoming_from"> <p>请填写您的个人信息</p> < ...

  8. Windows下QT4.8.4编译环境的搭建(转载http://blog.csdn.net/bestgonghuibin/article/details/38933141)

    开始使用QT了,所以第一步就是把环境搭起来,这里小记一下,以免以后忘记. 1. 下载安装文件 要使用QT功能,那么必须要下载QT的源码,还必须要一个是用QT的编译环境,可以是VS2010,也可以是专用 ...

  9. LibRTMP优化之调整输出块大小

    1. 为什么要调整输出块大小 首先在RTMP_Connect0函数中LibRTMP是关闭了Nagle算法这个TCP选项的,为了实时性这样做是好的,但是要注意到LibRTMP的结构体RTMP的成员是有m ...

  10. perl Socket接收超时设置

    一般来说, IO::Socket::INET里的Timeout设置是对于conncet的 如果你想设置recv接收超时, 可以这样设置: usr Socket: ...... , )); #注意这里p ...