clipper库使用的一些心得
clipper
sourceforge官网:http://sourceforge.net/projects/polyclipping/
1. 版本号差异
之前project里面使用4.8.6,近期升级到最新版本号6.2.1。接口层面有点区别:
老版本号使用Polygon概念,最新版本号用Path取代了Polygon。对用的Polygons用Paths取代,Clipper::AddPath的时候还须要制定是否封闭。
2. 注意数据类型
一个測试,回字上半部分和下半部分,两半部分进行合并,可是输出结果总是不正确:
void transform_array_to_path(int* arr, int size, ClipperLib::Path& path, int scale = 1)
{
for (int i = 0; i < size; i += 2)
{
path.push_back(ClipperLib::IntPoint(arr[i] * scale, arr[i + 1] * scale));
}
} void ClipperTest::merge_case()
{
using namespace ClipperLib; Clipper union_worker;
Paths solution; Path positive_path;
{
int points[] = { 1, 1, 1, 0, 2, 0, 2, 2, -2, 2, -2, 0, -1, 0, -1, 1 };
transform_array_to_path(points, sizeof(points) / sizeof(points[0]), positive_path, 10);
} union_worker.AddPath(positive_path, ClipperLib::ptSubject, true); Path negative_path;
{
int points[] = { 1, -1, 1, 0, 2, 0, 2, -2, -2, -2, -2, 0, -1, 0, -1, -1 };
transform_array_to_path(points, sizeof(points) / sizeof(points[0]), negative_path, 10);
} union_worker.AddPath(negative_path, ClipperLib::ptClip, true); union_worker.Execute(ClipperLib::ctUnion, solution, pftEvenOdd, pftEvenOdd); for (int k = 0; k < solution.size(); k++)
{
Path& path = solution[k]; printf("[ %dth ] : ", k + 1); for (int t = 0; t < path.size(); t++)
{
printf("%d,%d ", path[t].X, path[t].Y);
}
printf("\n");
}
}
合并后的结果输出:
// [1th] : -10, -1 - 10, -1 10, 0 10, 0
// [2th] : -20, -1 - 20, -1 20, 0 20, 0
结果百思不得其解,结果怎么是一个线段了。莫名其妙???正确结果例如以下图。合并后是一个回字型。
不断地跟clipper自带的demo程序比对,最终发现了问题所在:问题出在Clipper内部的IntPoint,假设未定义宏use_int32。採用的是long long存储顶点XY值。而上面code中printf是%d。使用%lld或者cout 就没问题了。坑啊。。。
2. 带洞多边形和多边形填充规则
围绕数和填充规则的示比例如以下图:

void ClipperTest::polygon_with_hole_merge_test()
{
using namespace ClipperLib; Path path1_outer;
Path path1_inner;
{
int outer[] = { -2, -2, 2, -2, 2, 2, -2, 2 };
int inner[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
transform_array_to_path(outer, sizeof(outer)/sizeof(outer[0]), path1_outer);
transform_array_to_path(inner, sizeof(inner)/sizeof(inner[0]), path1_inner);
} Path path2;
{
int outer[] = { 2, 2, 3, 2, 3, -2, 2, -2 };
transform_array_to_path(outer, sizeof(outer) / sizeof(outer[0]), path2);
} Paths sub_poly;
sub_poly.push_back(path1_outer);
sub_poly.push_back(path1_inner); Clipper union_worker;
union_worker.AddPaths(sub_poly, ptSubject, true);
union_worker.AddPath(path2, ptClip, true); Paths solution;
union_worker.Execute(ClipperLib::ctUnion, solution, pftEvenOdd, pftEvenOdd); for (int k = 0; k < solution.size(); k++)
{
Path& path = solution[k]; printf("[ %dth ] : ", k + 1); for (int t = 0; t < path.size(); t++)
{
// printf("%d,%d ", path[t].X, path[t].Y);
cout << path[t].X << "," << path[t].Y << " ";
} printf("\n");
}
}
不用care顶点顺序,效果图例如以下:
clipper库使用的一些心得的更多相关文章
- Clipper库中文文档详解
简介 Clipper Library(以下简称为Clipper库或ClipperLib或Clipper)提供了对线段和多边形的裁剪(Clipping)以及偏置(offseting)的功能 和其他的裁剪 ...
- gdal库的三个使用心得
作者:朱金灿 来源:http://blog.csdn.net/clever101 最近使用gdal库比较多,就谈谈gdal库的一些使用心得. 第一个是GDALOpen的访问权限参数会影响图像的创建金字 ...
- 软工实践练习一——使用Git进行代码管理心得
在github.com的操作 注册 创建Organization 将指定代码库fork到小组Organization下 在Organization下创建repository 这些操作在学校的机房已经完 ...
- Python中第三方的用于解析HTML的库:BeautifulSoup
背景 在Python去写爬虫,网页解析等过程中,比如: 如何用Python,C#等语言去实现抓取静态网页+抓取动态网页+模拟登陆网站 常常需要涉及到HTML等网页的解析. 当然,对于简单的HTML中内 ...
- 开发者必备的 12 个 JavaScript 库
现在 web 设计是最有趣的了,做好 web 设计不仅要熟练使用 Javascript,css 和 html 等,还要有自己的创意设计.为了方便大家发挥自己的创意,就产生了很多 JS 框架,Node. ...
- python标准库学习-SimpleHTTPServer
这是一个专题 记录学习python标准库的笔记及心得 简单http服务 SimpleHTTPServer 使用 python -m SimpleHTTPServer 默认启动8000端口 源码: &q ...
- 动态链接库(DLL)总结
以前的学习笔记,记录库的一点学习心得.主要是Windows下的静态库和动态链接库,动态链接库只写了关于非MFC的DLL,比较初级,适合和我一样的新手看看.有不对的地方请指出,有疏漏的地方请补充,如果您 ...
- python常见的模块
Python内置模块名称 功能简介 详细解释/使用示例 os 和操作系统相关 os.path — Common pathname manipulations sys 和系统相关 sys — Syste ...
- (转)用AGG实现高质量图形输出(一)
AGG是一个开源.高效的跨平台2D图形库.AGG的功能与GDI+的功能非常类似,但提供了比GDI+更灵活的编程接口,其产生的图形的质量也非常高(自称超过GDI+) 使用前AGG的准备工作 下载AGG库 ...
随机推荐
- 一个 passive 引发的bug
不是什么很难的东西,权且做个记录. 首先说下背景,目前的项目中,需要同时绑定 wheel 和 scroll 事件. 绑定 wheel,目的是开发 ctrl + wheel 缩放页面功能,此功能与浏览器 ...
- Springboot使用AOP实现统一处理Web请求日志
1.要使我们自定义的记录日志能够打印出来,我们需要先排除springboot默认的记录日志,添加如下的设置 2.新建 resources/log4j.properties 我的设置为: # LOG4J ...
- NOIP 2013 T2 火柴排队 ---->求逆序对
[NOIP2013T2]火柴排队 背景 noip2013day1 描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各 自 排成一列, 同一列火柴的高度互不相同, ...
- 如何使用fetch
Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取 ...
- (转载) android studio library生成jar包和aar的方法总结
android studio library生成jar包和aar的方法总结 标签: android学习文档jar和aar的使用与生成gradle 2016-11-25 10:39 1782人阅读 评论 ...
- lz的第一个RN项目
这是lz 成功在原有项目上集成的第一个ReactNative 项目. 参考官方网址: http://reactnative.cn/docs/0.43/integration-with-existing ...
- Github 团队协作基本流程与命令操作 图解git工作流程
# 先 fork 项目到自己 github # 1. 从自己仓库克隆到本地(clone 的是项目指定的默认分支,比如 master) git clone git@github.com:me/em.gi ...
- 路飞学城Python-Day113
107-HTTP协议的无状态保存 什么是无状态保存? HTTP无状态请求就是客户端每次发送的请求都是单独的新请求,每一次请求都是独立的,这样的特点在网站上就是服务器登录的时候记录浏览器的信息,建立 ...
- Django之组合查询
一 .Django组合查询 很多电商网站中有组合搜索的功能,所谓组合搜索就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,下面是所做组合查询效果图: 实现代码如下: <1> ...
- 「Poetize4」创世纪
在tyvj上怀疑爆栈了.....或许一定是我写挂了.以后调吧... UPD:bzoj上过了... 题解:https://blog.csdn.net/popoqqq/article/details/39 ...