C-9 多边形

C-9 多边形

多边形的定义

  • 由一组连续存放的点定义多边形,依次连接点并且起始点与结束点相连。围成的图形就是多边形

  • //定义了一个正方形
    pair<int,int> polygon[4] ={{0,0},{100,0},{100,100},{0,100}}
    

判断一个点是否在多边形内部

  • 根据该点引出的射线与多边形边的交点个数的奇偶来判断。如果一个点引出的射线,与多边形的交点是偶数,那么就在多边形外部,是奇数就在多边形内部。注意是射线与多边形边的交点,与多边形顶点的交点不算在内部。

计算多边形的面积

  • 将多边形进行三角剖分,分成一个个的三角形,计算每个三角形的面积并累加就是多边形的面积了。
  • 关于三角剖分的方法在之后会介绍

两个多边形是否相交

  • 遍历其中一个多边形的每一条边判断是否与另一个多边形的边相交

多边形的剪裁(多边形求交)

  • GitHub上的开源项目clipper2就解决了这一问题
  • 绿色部分就是淡红色和淡蓝色这两个多边形的交集,当然也是一个多边形

image-20240624192618696

求多边形的包围线

  • 如下图(圆可看成离散化的多边形),给定一个多边形如何求出环绕着这个多边形的包围线呢?这里我回答了上一篇一笔带过的问题。

  • 这个问题在绘制PCB电路里有应用,用kicad等等之类的工具绘制的线段都是带有一定宽度的,当然不止在绘制PCB电路里应用,可能还有一些其他的绘制场景里也用到了该方法。

  • 在思想上可以这么思考。对于求给定的线宽r,将一个可以以r为半径的圆的圆心放置在多边形或者链条(没有闭合的多边形)的轨道上,将该圆沿着多边形(链条)进行平移,圆留下的轨迹就是我们需要的包围线。也看成多边形相交和拐角处理的问题。

  • 在kicad中,是用clipper这一函数库进行处理的,对于pcb电路的轨迹,输入一条线段,kicad就提供方法,将这一条没有宽度的线段进行求包围线,输出为一条有宽度的线段,最终呈现在屏幕上。

  • image-20240624194838340

  • C-8-1
    在这里插入图片描述

  • 截取项目里的一些代码,来展示如何使用clipper2来获得输入链条的包围线,非常方便,效率也不错。

  • 当然clipper2的网址也有相关说明

  • void myGeometry::createLine(const char* path) {
    	outline.createOutLine(path);
    	int mark = 100;
    	for (int i = 0; i < outline.OutLinePoints.size(); i++) {
    		Clipper2Lib::Path64 clipper_polygon;
    
    		for (int j = 0; j < outline.OutLinePoints[i].size(); j++) {
    			int x = outline.OutLinePoints[i][j].X() * mark;
    			int y = outline.OutLinePoints[i][j].Y() * mark;
    
    			clipper_polygon.push_back(Clipper2Lib::Point64(x, y));
    		}
            
            
    		Clipper2Lib::ClipperOffset offset;
    		offset.AddPath(clipper_polygon, Clipper2Lib::JoinType::Miter, Clipper2Lib::EndType::Joined);
    		Clipper2Lib::Paths64 solution;
            //进行包围线的输出!!!
    		offset.Execute(13 * mark, solution);
    		std::vector<std::vector<std::array<LONG64, 2>>> temp_polygon;
    
    		
    		for (int j = 0; j < solution.size(); j++) {
    			auto path = solution[j];
    			std::vector<std::array<LONG64, 2>> trace;
    
    			for (int k = 0; k < solution[j].size(); k++) {
    
    				std::array<LONG64, 2> p = { path[k].x, path[k].y };
    				trace.push_back(p);
    			}
    			temp_polygon.push_back(trace);
    			createSideMesh(trace,100*mark);
    		}
    		Polygons.push_back(temp_polygon);
    	}
    
    }
    
    

参考资料

  • clipper2: https://github.com/AngusJohnson/Clipper2
  • 9
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值