clipper

sourceforge官网:http://sourceforge.net/projects/polyclipping/

1. 版本号差异

之前project里面使用4.8.6,近期升级到最新版本号6.2.1。接口层面有点区别:

老版本号使用Polygon概念,最新版本号用Path取代了Polygon。对用的Polygons用Paths取代,Clipper::AddPath的时候还须要制定是否封闭

2. 注意数据类型

一个測试,回字上半部分和下半部分,两半部分进行合并,可是输出结果总是不正确:

  1. void transform_array_to_path(int* arr, int size, ClipperLib::Path& path, int scale = 1)
  2. {
  3. for (int i = 0; i < size; i += 2)
  4. {
  5. path.push_back(ClipperLib::IntPoint(arr[i] * scale, arr[i + 1] * scale));
  6. }
  7. }
  8.  
  9. void ClipperTest::merge_case()
  10. {
  11. using namespace ClipperLib;
  12.  
  13. Clipper union_worker;
  14. Paths solution;
  15.  
  16. Path positive_path;
  17. {
  18. int points[] = { 1, 1, 1, 0, 2, 0, 2, 2, -2, 2, -2, 0, -1, 0, -1, 1 };
  19. transform_array_to_path(points, sizeof(points) / sizeof(points[0]), positive_path, 10);
  20. }
  21.  
  22. union_worker.AddPath(positive_path, ClipperLib::ptSubject, true);
  23.  
  24. Path negative_path;
  25. {
  26. int points[] = { 1, -1, 1, 0, 2, 0, 2, -2, -2, -2, -2, 0, -1, 0, -1, -1 };
  27. transform_array_to_path(points, sizeof(points) / sizeof(points[0]), negative_path, 10);
  28. }
  29.  
  30. union_worker.AddPath(negative_path, ClipperLib::ptClip, true);
  31.  
  32. union_worker.Execute(ClipperLib::ctUnion, solution, pftEvenOdd, pftEvenOdd);
  33.  
  34. for (int k = 0; k < solution.size(); k++)
  35. {
  36. Path& path = solution[k];
  37.  
  38. printf("[ %dth ] : ", k + 1);
  39.  
  40. for (int t = 0; t < path.size(); t++)
  41. {
  42. printf("%d,%d ", path[t].X, path[t].Y);
  43. }
  44. printf("\n");
  45. }
  46. }

合并后的结果输出:

  1. // [1th] : -10, -1 - 10, -1 10, 0 10, 0
  2. // [2th] : -20, -1 - 20, -1 20, 0 20, 0

结果百思不得其解,结果怎么是一个线段了。莫名其妙???正确结果例如以下图。合并后是一个回字型。

不断地跟clipper自带的demo程序比对,最终发现了问题所在:问题出在Clipper内部的IntPoint,假设未定义宏use_int32。採用的是long long存储顶点XY值。而上面code中printf是%d。使用%lld或者cout 就没问题了。坑啊。。。

2. 带洞多边形和多边形填充规则

clipper中定义了,EvenOdd,NonZero。Positive。Negative四中填充规则。相应參考OpenGL红皮书上关于多边形填充规则的说明:http://glprogramming.com/red/chapter11.html

多边形填充规则的使用引入了一个围绕数(Winding Numbers)和围绕规则(Winding Rules)的概念。围绕规则一般CCW为正。CW为负。

围绕数和填充规则的示比例如以下图:



为了表示一个带洞的多边形,比如上图中的回字型。须要内外两个路径表示,那么须要注意顶点的存储顺序吗? 这个问题的答案是,取决于多边形的填充规则。假设使用EvenOdd规则,则不用关心顶点的存储顺序。由于:第一圈为+1/-1,一定是奇数,然后加1或者减1,结果都是偶数。然后再加1或减1结果一定是奇数

有了这个认识。我们写个測试样例,一个回字。跟一个四边形即可融合,Subject是一个Paths。包括两个Path表示。内外圈顺序无关;Clip是一个Path。进行合并的结果包括两个Path。
  1. void ClipperTest::polygon_with_hole_merge_test()
  2. {
  3. using namespace ClipperLib;
  4.  
  5. Path path1_outer;
  6. Path path1_inner;
  7. {
  8. int outer[] = { -2, -2, 2, -2, 2, 2, -2, 2 };
  9. int inner[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
  10. transform_array_to_path(outer, sizeof(outer)/sizeof(outer[0]), path1_outer);
  11. transform_array_to_path(inner, sizeof(inner)/sizeof(inner[0]), path1_inner);
  12. }
  13.  
  14. Path path2;
  15. {
  16. int outer[] = { 2, 2, 3, 2, 3, -2, 2, -2 };
  17. transform_array_to_path(outer, sizeof(outer) / sizeof(outer[0]), path2);
  18. }
  19.  
  20. Paths sub_poly;
  21. sub_poly.push_back(path1_outer);
  22. sub_poly.push_back(path1_inner);
  23.  
  24. Clipper union_worker;
  25. union_worker.AddPaths(sub_poly, ptSubject, true);
  26. union_worker.AddPath(path2, ptClip, true);
  27.  
  28. Paths solution;
  29. union_worker.Execute(ClipperLib::ctUnion, solution, pftEvenOdd, pftEvenOdd);
  30.  
  31. for (int k = 0; k < solution.size(); k++)
  32. {
  33. Path& path = solution[k];
  34.  
  35. printf("[ %dth ] : ", k + 1);
  36.  
  37. for (int t = 0; t < path.size(); t++)
  38. {
  39. // printf("%d,%d ", path[t].X, path[t].Y);
  40. cout << path[t].X << "," << path[t].Y << " ";
  41. } printf("\n");
  42. }
  43. }

不用care顶点顺序,效果图例如以下:




clipper库使用的一些心得的更多相关文章

  1. Clipper库中文文档详解

    简介 Clipper Library(以下简称为Clipper库或ClipperLib或Clipper)提供了对线段和多边形的裁剪(Clipping)以及偏置(offseting)的功能 和其他的裁剪 ...

  2. gdal库的三个使用心得

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近使用gdal库比较多,就谈谈gdal库的一些使用心得. 第一个是GDALOpen的访问权限参数会影响图像的创建金字 ...

  3. 软工实践练习一——使用Git进行代码管理心得

    在github.com的操作 注册 创建Organization 将指定代码库fork到小组Organization下 在Organization下创建repository 这些操作在学校的机房已经完 ...

  4. Python中第三方的用于解析HTML的库:BeautifulSoup

    背景 在Python去写爬虫,网页解析等过程中,比如: 如何用Python,C#等语言去实现抓取静态网页+抓取动态网页+模拟登陆网站 常常需要涉及到HTML等网页的解析. 当然,对于简单的HTML中内 ...

  5. 开发者必备的 12 个 JavaScript 库

    现在 web 设计是最有趣的了,做好 web 设计不仅要熟练使用 Javascript,css 和 html 等,还要有自己的创意设计.为了方便大家发挥自己的创意,就产生了很多 JS 框架,Node. ...

  6. python标准库学习-SimpleHTTPServer

    这是一个专题 记录学习python标准库的笔记及心得 简单http服务 SimpleHTTPServer 使用 python -m SimpleHTTPServer 默认启动8000端口 源码: &q ...

  7. 动态链接库(DLL)总结

    以前的学习笔记,记录库的一点学习心得.主要是Windows下的静态库和动态链接库,动态链接库只写了关于非MFC的DLL,比较初级,适合和我一样的新手看看.有不对的地方请指出,有疏漏的地方请补充,如果您 ...

  8. python常见的模块

    Python内置模块名称 功能简介 详细解释/使用示例 os 和操作系统相关 os.path — Common pathname manipulations sys 和系统相关 sys — Syste ...

  9. (转)用AGG实现高质量图形输出(一)

    AGG是一个开源.高效的跨平台2D图形库.AGG的功能与GDI+的功能非常类似,但提供了比GDI+更灵活的编程接口,其产生的图形的质量也非常高(自称超过GDI+) 使用前AGG的准备工作 下载AGG库 ...

随机推荐

  1. hdoj--2015--偶数求和(水题)

    偶数求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  2. sublime界面主题

    一直以来都是使用的SUBLIME,真的很强大. 最近刚转到linux来学习C,把它重新配置了一遍,默认的字体颜色的搭配已经很不错了.不过界面的样子还是不太习惯.重新安装了下soda这个主题包,惭愧!即 ...

  3. [转载]linux上安装oracle

    原文地址:linux上安装oracle作者:天涯恨客 1.创建oinstall组 [root@xieqing ~]# groupadd oinstall 创建dba组 [root@xieqing ~] ...

  4. CTF-Mayday

    打开下载的Mayday.txt文件: 温柔 知足突然好想你  拥抱突然好想你  拥抱温柔 知足温柔 知足突然好想你  拥抱突然好想你  拥抱温柔 知足温柔 知足突然好想你  拥抱突然好想你  拥抱温柔 ...

  5. RT-Thread 设备驱动SPI浅析及使用

    OS版本:RT-Thread 4.0.0 测试BSP:STM32F407 SPI简介 SPI总线框架其实和I2C差不多,可以说都是总线设备+从设备,但SPI设备的通信时序配置并不固定,也就是说控制特定 ...

  6. iOS布局---pch头文件设置和字号适配

    由于4s,5s,6,6p,界面尺寸差别过大,如果在界面上,只是用同一个字号,在4s和5s上就会略显偏大,而在6p上就会显小.并且ios9系统原生字体相较于ios8和之前原生字体略粗,在字号上也错了一号 ...

  7. .net 对称加密

    后台   public class CryptoHelper     {         // 对称加密算法提供器         private ICryptoTransform encryptor ...

  8. html+css布局整理笔记

    基本概念 布局模型 流动模型(Flow) 浮动模型(Float) 层模型(Layer) 流动模型 默认的网页布局模式,流动布局模型有两个比较典型的特征: 第一,块级元素都会在所处的包含元素内自上而下按 ...

  9. 详解优动漫PAINT中的图层模式

    使用优动漫PAINT绘制漫画或者插画的时候,在其新建画布区域有一个基本颜色模式的选项,分别包括彩色模式.灰度模式和黑白位图模式,那么这三个模式有什么区别呢,我们在绘图的时候应该如何选择呢? 彩色模式: ...

  10. 洛谷P1540 机器翻译 水题 模拟

    注意一下细节,尤其是更新minv时不要更新错. Code: #include<vector> #include<iostream> #include<cstdio> ...