源代码:https://github.com/ricar0/Weiler-Atherton-Alogrithm/tree/master
什么是多边形裁剪
通常来说就是利用多边形来裁剪多边形的一种方法,一般情况下是利用矩形来裁剪凹凸多边形
- 凸多边形
- 凹多边形
上面红色划线部分就是裁剪出的部分
前置知识
- OPENGL基础语法
基本上就是一些画线和画多边形的操作,难度较低 - 求两直线交点
较为基础的数学知识 - 求一个点是否落在多边形内/外
计算几何知识 - Weiler-Atherton多边形裁剪算法
这里着重介绍Weiler-Atherton算法,其余不懂的可以先学会再看。
算法步骤
- 首先绘制两个相交的多边形
- 对于多边形1,我们从一个点出发,将所有经过的点(包含交点)存入新的数组中,对于多边形2也是同理
- 对两个新数组中的相同点进行点对映射
- 开始对裁剪多边形1进行遍历,从任意点出发,如果改点将从多边形2的内部穿越到外部,我们改变遍历点的对象,从多边形2开始遍历,依次类推…
- 直到当前点被遍历过,那么之前肯定形成了一个回路,我们将当前回路绘制出来就是裁剪出的多边形。
- 一直重复4和5操作,直到所有点都被遍历
接下来结合图片解释一下
对于如下这个图,我们利用矩形裁剪凹多边形。
首先从E点出发,判断E到J是否为出点,发现不是。遍历到J点,判断JF是否是出点,发现是,这时候改变遍历的对象,通过映射关系从K点开始。判断发现KC又是出点,因此再次改变遍历对象,遍历多边形到E,发现J已经被遍历过,这时直接绘制出JKE…
程序框图
代码实现
建立窗口以及自动调整大小
1 | void reshape(int w, int h) { |
建立点和线
1 | struct Point2d { |
求两条线段交点的模板,如果不存在返回-inf
1 | inline Point2d Vector(Point2d a, Point2d b) { //向量ab |
求两点距离,用于排序
1 | double dis(Point2d point1, Point2d point2) { |
判断点是否落在多边形内,这里加了个误差0.001
1 | bool isPointInsidePoly(Point2d P,const vector<Point2d>& polyVertices) { |
求交点以及重新放入数组
1 | void getIntersections() {//求出所有交点以及按照顺序存放在新数组中 |
绘制两个多边形以及初始化操作
1 | void prework() { |
最核心的代码,遍历两个多边形
1 | void work() { |
这里存入需要绘制的两个多边形,按顺序存
1 | void init() { |