【图形学】多边形裁剪算法综述

news2024/11/24 5:07:02

系列综述:
💞目的:本文是个人学习多边形裁剪知识整理的,整理期间努力理解论文作者含义,并增加了自己的详述和注解。
🥰来源:材料主要源于多边形裁剪相关论文进行的,每个知识点的学习和深入主要参考各平台大佬的文章
🤭结语:如果有帮到你的地方,就点个赞关注一下呗,谢谢🎈🎄🌷!!!


文章目录

    • 概述
      • 基本概念
    • 国外著名多边形裁剪算法
      • 矩形窗口裁剪算法
      • Greiner-Hormann算法
      • Weiler-Atherton裁剪算法
      • Sutherland-Hodgman算法
      • 其他算法
    • 国内著名多边形裁剪算法
      • 1996鲍虎军,彭群生. 一个有效的多边形裁剪算法
      • 2003刘勇奎,高云,黄有群. 一个有效的多边形裁剪算法
      • 2002陆国栋,邢世海,彭群生. 基于顶点编码的多边形窗口线裁剪高效算法
      • 2006白晨. 一种任意多边形的裁剪算法
      • 2006付迎春,袁修孝.一种有效的任意多边形裁剪算法
    • 数控系统的工艺融合论文思路
      • 问题
      • 规则
      • 思路(有问题)
      • 思路2
      • 特殊问题
  • idea
    • 线裁剪算法
    • 参考博客


😊点此到文末惊喜↩︎


概述

基本概念

  1. 多边形的类型
    • 前提:多边形的每一个内角都是由两条相邻边形成的
    • 凸多边形:多边形的所有内角均小于180°
    • 凹多边形:多边形bm存在内角大于180°的内角
    • 带内环的多边形
      在这里插入图片描述
      在这里插入图片描述
  2. 国外著名多边形裁剪算法
    • 矩形窗口裁剪算法
    • Greiner-Hormann裁剪算法《Efficient clipping of arbitrary polygons》?
    • Sutherland-Hodgman算法 《Reentrant polygon clipping》
    • Vatti裁剪算法《A Generic Solution to Polygon Clipping》
    • Weiler-Atherton裁剪算法《Hidden surface removal using polygon area sorting》
  3. 国内著名多边形裁剪算法
    • 鲍虎军,彭群生. 一个有效的多边形裁剪算法
    • 刘勇奎,高云,黄有群. 一个有效的多边形裁剪算法
    • 陆国栋,邢世海,彭群生. 基于顶点编码的多边形窗口线裁剪高效算法
    • 白晨.一种任意的多边形裁剪算法

国外著名多边形裁剪算法


矩形窗口裁剪算法

  1. 矩形裁剪的基本规则
    • 如果直线的两个端点都在窗口边界之内,如ab,则直线保留
    • 如果直线的一个端点在窗口边界之内,另一个端点在窗口边界之外,如ef,则应从直线与边界的交点处裁剪掉边界之外的线段
    • 如果直线的两个端点都在窗口边界之外,有两种情况:
      • 一种情况如ij,直线全部在窗口之外,应该全部裁减掉;
      • 另一种情况如gh,直线横穿窗口边界,应该保留相交的片段,裁减掉剩余的片段
        在这里插入图片描述
  2. 1968Cohen-Sutherland裁剪算法(编码裁剪算法)
    • 先对端点P1和P2进行编码,P1的编码 : code1 P2的编码 : code2
    • 完全在窗口内,则有 code1 | code2 = 0
    • 完全在窗口外,则有 code1 & code2 != 0
    • 与窗口相交,求交,将窗口外的线段丢弃,再进行裁剪
      在这里插入图片描述
  3. Newman-Sproul直线段中点分割裁剪算法
    • 先对端点P1和P2进行编码,P1的编码 : code1 P2的编码 : code2
    • 完全在窗口内,则有 code1 | code2 = 0
    • 完全在窗口外,则有 code1 & code2 != 0
    • 上面两种情况都不符合,则求交点。
      • P与P1同侧,则交点在P和P2之间,则将P点的坐标赋值给P1;
      • P与P2同侧,则交点在P和P1之间,则将P点的坐标赋值给P2。
      • 之后递归对中点进行分割,则可以收敛到交点。
        在这里插入图片描述
  4. 梁友栋-Barsky裁剪算法
    在这里插入图片描述
    在这里插入图片描述

Greiner-Hormann算法

  1. 特点
    • 每个多边形均采用双链表进行表示,每找到一个交点就分别插入实体多边形和裁剪多边形的
    • 基于布尔运算的多边形裁剪算法,它可以处理自相交和重叠的情况。

Weiler-Atherton裁剪算法

  1. 特点
    • 裁剪窗口和被裁剪多边形可以是任意多边形:凸的、凹的
    • 相比之前的多边形裁剪算法,平均性能最好的
    • 在有重合边和与多边形顶点相交时会出现失效的情况,且处理带环多边形之间的裁剪效率低。
  2. 算法流程
    • 从被裁剪多边形的一个入点开始,碰到入点,则沿着被裁剪多边形按顺时针方向搜集出点,并将出点放如输出多边形顶点序列(为防止在处理分裂多边形时失效,算法要将搜集过的入点的入点标记删去,以免重复跟踪。)
    • 再沿着裁剪窗口按顺时针方向搜集顶点序列,直到遇到下一个入点,此过程中如遇到被裁剪多边形的顶点,则将顶点按照查找的顺序插入到输出顶点序列中。
    • 按上述规则,交替地沿着被裁剪多边形和裁剪窗口的边界行进,直到回到起始点。
    • 收集到的全部顶点序列就是裁剪所得的多边形。
      在这里插入图片描述

Sutherland-Hodgman算法

  1. 基本概述
    • Sutherland-Hodgman算法也叫逐边裁剪法,该算法是萨瑟兰德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的。这种算法采用了分割处理、逐边裁剪的方法
  2. 特点
    • 被裁剪多边形可以是任意凸多边形或凹多边形,裁剪窗口不局限于矩形,可以是任意凸多边形。
  3. 基本思想
    • 窗口的一条边以及延长线构成的裁剪线该线把平面分成两个部分:可见一侧;不可见一侧。多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种
      在这里插入图片描述
      • 情况(1):被裁减的线段端点均在可见一侧,则只输出顺时针方向的P点
      • 情况(2):被裁减的线段均在不可见一侧,则不输出顶点
      • 情况(3):被裁减的线段端点在两侧,则只输出线段SP与裁剪窗口边界的1个交点I;
      • 情况(4):被裁减的线段端点在两侧,则输出P端点和线段与裁剪窗口边界的1个交点I;
  4. 示例
    • 顺时针访问多边形各条边,可以以上面的基本思想来对上图多边形进行裁剪,可以得到正确的结果
      在这里插入图片描述
  5. 具体算法设计
//点在有向线段那侧
/*
向量叉积法
    为简单计,测试点表示为P点。假设窗口边界方向为顺时针,如图中所示,对于其中任一边界向量,从向量起点A向终点B看过去:
	  如果被测试点P在该边界线右边(即内侧),AB×AP的方向与X-Y平面垂直并指向屏幕里面,即右手坐标系中Z轴的负方向。
	    反过来,如果P在该边界线的左边(即外侧),这时AB×AP的方向与X-Y平面垂直并指向屏幕外面,即右手坐标系中Z轴的正方向。
		  设:点P(x,y)、点A(xA,yA)、点B(xB,yB),
		    向量AB={(xB-xA),(yB-yA)},
		    向量AP={(x-xA),(y-yA)},
		
		    那么AB×AP的方向可由下式的符号来确定:
		  
			V=(xB-xA)·(y-yA)-(x-xA)·(yB-yA) // V为AB叉乘AP的结果向量中的z分量
			
			    因此,当V≤0时,P在边界线内侧;
				    而V>0时,P在边界线外侧。
*/
typedef point
{
	int x;
	int y;
}RtPoint;
 
typedef struct
{
	RtPoint sp; //裁剪窗口边界向量起点
	RtPoint ep; //裁剪窗口边界向量终点
}_RtInSide;
 
static int _RtInSide(RtVector vector, RtPoint point) // 计算上面的V,vector为裁剪窗口边界向量,point为上面的p点
{
	return (vector.ep.x - vector.sp.x) * (point.y - vector.sp.y) - (vector.ep.y - vector.sp.y) * (point.x - vector.sp.x);
}
 
//多边形点必须是顺时针方向
// src保存的是裁剪窗口坐标点,应该是顺时针方向保存,num为裁剪窗口边界数量,*dest保存裁剪后的多边形顶点数组,*total为*dest大小
int rtPrunePSH(RtPoint* src, int num, RtPoint** dest, int* total)
{
	int i = 0, j = 0, k = -1, flag = 0;
	RtPoint start, stop;//被剪裁多边形的边向量起点和终点
	RtPoint sp, ep;//剪裁窗口边界向量的起点和终点
	RtPoint* temp = NULL;  // temp保存针对某一裁剪窗口边界裁剪后的新坐标
	temp = (RtPoint*)malloc(sizeof(RtPoint) * 3 * (*total));
	if (temp == NULL) return -1;
	
	sp = *(src + num - 1);
 
	for ( i = 0; i < num; i++)//剪裁窗口
	{
		ep = *(src + i);
		
		start = *((*dest) + *total - 1);
		flag = _RtInSide(rtVector(sp, ep), start) > 0 ? 0 : 1; //在外侧,flag为0,在内侧时flag为1
 
		for ( j = 0; j < *total; j++)//被剪裁的多边形
		{	
			stop = *((*dest) + j);
			if (_RtInSide(rtVector(sp, ep), stop) <= 0)//当前第i个顶点是否在边界内侧
			{
				if (flag == 0)/*前一个点在外侧吗?*/
				{
					flag = 1;/*从外到内的情况,将标志置1,作为下一次循环的前一点标志*/
					k++;
					CRtPoint<double> point;
					CRtPoint<int> st(sp.x, sp.y), et(ep.x, ep.y);	 			
					CRtLine<int> v1(st, et);//v1为由窗口边界向量起点sp和终点ep组成的直线
					st.SetData(start.x, start.y);
					et.SetData(stop.x, stop.y); //v2为由多边形当前边起点start和终点stop组成的直线
					CRtLine<int> v2(st, et); 
					v2.Intersect(v1,point);  //两直线求交运算,交点保存到point数组里面
					(temp + k)->x = point[0];/*将交点放入新多边形*/ 
					(temp + k)->y = point[1];
				}
				k++;
				*(temp + k) =  stop;/*将当前点pi放入新多边形*/ 
			}
			else
			{
				if (0 != flag)/*前一个点在内侧吗?*/
				{
					flag = 0;/*从内到外的情况,将标志置1,作为下一次循环的前一点标志*/
					k++;
					CRtPoint<double> point;  // 同上面一样
					CRtPoint<int> st(sp.x, sp.y), et(ep.x, ep.y);					
					CRtLine<int> v1(st, et);
					st.SetData(start.x, start.y);
					et.SetData(stop.x, stop.y);
					CRtLine<int> v2(st, et);
					v2.Intersect(v1,point);
					(temp + k)->x = point[0];/*将交点放入新多边形*/ 
					(temp + k)->y = point[1];
				}
			}
			start = stop;/*将当前点作为下次循环的前一点*/
		}
 
		sp = ep;
		*total = k + 1; // k+1为一次裁剪后生成的新坐标点的数量
		memcpy(*dest, temp, sizeof(RtPoint) * (*total));
		k = -1;
	}
 
	return 0;
}

其他算法

  1. Vatti是一个利用扫描线和优先队列的多边形裁剪算法,它可以处理任意形状的多边形
  2. Polygon Reconstruction算法:这是一个可以从一组线段重建多边形的算法,它可以处理裁剪后产生的不连通的多边形。
  3. Line Clipping算法:这是一个可以将线段按照一个多边形进行裁剪的算法,它可以处理任意形状的多边形1。
  4. Cyrus-Beck算法:这是一个针对任意凸多边形裁剪区域的线段裁剪算法,它使用参数化方程和点积来判断线段是否可见23。

国内著名多边形裁剪算法

1996鲍虎军,彭群生. 一个有效的多边形裁剪算法

  1. 算法流程:
    • 两个多边形分别为P和Q,为每个多边形建立一个双向的环形链表。
    • 从被裁剪多边形Q的链表中取出一个状态为in的线段,从该线段出发,按照顺时针跟踪多边形表,直到发现下一线段状态为out为止

2003刘勇奎,高云,黄有群. 一个有效的多边形裁剪算法

  1. 特点
    • 可适应于一般多边形、凹多边形和具有内孔的多边形
    • 不仅可以求多边形的交(多边形裁剪),还可以求出多边形的并和差
    • 使用单链表作为基本数据结构
    • 可以求具有多个分立多边形的情况
  2. 基本概念
    • 基本数据结构:每个多边形用一个循环单链表进行表示,单链表中的节点是多边形的一个顶点,并且顺时针顺序存储 (循环的意义是多边形是封闭的)
    • 顺右逆左:边的方向按顺时针走则规定右边为内部,边的方向按逆时针走则规定左边为内部。具有孔洞的多边形,内部以相反的规则进行内外判定
    • 设I是多边形S和C的交点,C固定不动S沿边界走
      • 进点:S从C的外部到内部形成的交点I
      • 出点:S从C的内部到外部形成的交点I
        在这里插入图片描述
    • 进点和出点的判定
      • S i S_i SiC的外点,则 S i S_i Si沿S的边界与C的第一个交点必然是进点
      • S i S_i SiC的内点,则 S i S_i Si沿S的边界与C的第一个交点必然是出点
      • 进点和出点是依次出现的,所以只要判定第一个交点是进点or出点,其他交点按序即可确定进出性
  3. 数据结构的定义
    // 顶点的二维坐标
    struct coordinate{
    	int x;
    	int y;
    }
    // 顶点/交点的结构体
    struct vertex{
    	coordinate cord;// 顶点坐标
    	bool inters;// 本身是否为交点
    	bool used;// 用于有多个输出多边形时,初值为0,输出后置1
    	struct vertex *next1;// 插入到实体多边形链表
    	struct vertex *next2;// 若为交点则启用,插入到裁剪多边形链表
    }
    
  4. 算法基本流程
    • 阶段1:判断及计算第一个交点,并由其进出性判断两个多边形是否同向(原因是下面定理)。如果不同向则将裁剪多边形链表反向,然后将该交点插入到两个多边形的链表中
    • 阶段2:依次以实体多边形的每一个边对裁剪多边形进行直线裁剪操作,判断及计算其余交点,并以正确的顺序插入到两个多边形的链表中
    • 阶段3:遍历整个链表,输出最终结果
  5. 定理
    • 定理1:如果两个相交的多边形的边取向相同(均为顺时针或逆时针),则对一个多边形是进点的交点,对于另一个多边形必是出点(文中已证明)
    • 定理2:交点的进出性是按顺序依次交替的
    • 结论:两个同向多边形,交点的进出性只需要标记对于其中一个多边形的即可,对于另一个多边形进出性与其相反。
  6. 边裁剪算法
  7. 特殊情况的处理
    • 参考处理方法
      • 通过在链表上减少或增加交点,来保持进点和出点的交替出现。处理复杂
      • 对重合边的一个顶点或交点相同的顶点进行很小的移动来避免特殊情况。增加误差
    • 结论方法
      • 如果重合顶点数一数裁剪多边形,则只将该顶点的y坐标±一个单位使该点上下移动,因为实体多边形的当前边已经错切成水平线,所以不会仍然重合。如果重合顶点属于实体多边形,则只将该顶点的x坐标±一个单位使该点左右移动即可避开裁剪多边形的边
  8. 与其他算法的比较
    • 空间复杂度:相比于Vatti和Greiner-Hormann算法只占用了一半的存储单位
    • 时间复杂度 :由于减少域的设置量而节省了大量时间

2002陆国栋,邢世海,彭群生. 基于顶点编码的多边形窗口线裁剪高效算法

  1. 编码技术:以裁剪窗口为参照系,延长矩形窗口的四条边,将平面划分为九个区域,根据线段所在区域进行线段的编码。通过这种静态预编码,可以在运行时简洁高效的判断线段的状态。
  2. 裁剪算法目标:
    • 尽量避免求交运算
    • 尽可能加快求交进程
    • 快速有效处理特殊相交情况
  3. 裁剪分区
    • 包围盒:将上下左右的最外侧顶点连接形成的正方形,用于快速舍弃无用裁剪边。但是程序中可以通过对称处理,最终将四种情况简化成两种。
    • P点取裁剪直线与多边形窗口交点,在具体实现时,算法具有两个分支
      • |k| > 1
      • |k| ≤ 1
  4. 通过窗口编码技术可以排除大部分与多边形窗口不相交的裁剪直线,只剩下部分与窗口不相交的被裁减直线和所有的与窗口相交的被裁减直线
    • 部分与窗口不相交线段的消减:判断交点是否位于直线的延迟线上,如果在则为无效交点
  5. 特殊情况
    • 交点是顶点的情况
      • 裁剪线段两端位于多边形异侧,需要保存交点
      • 裁剪线段两端位于多边形同侧,不需要保存交点
        在这里插入图片描述
    • 被裁剪直线与窗口的某一边重合
      • 基本:构成包围盒的多边形顶点必是凸顶点,求以它们为顶点的向量的叉积,其它顶点的向量叉积若与极值点的向量叉积相同则为凸顶点,否则为凹顶点。
      • 凸顶点计入交点数据,凹顶点不需计入交点数组。
        在这里插入图片描述
  6. 算法流程
    在这里插入图片描述
  7. 总结:本文从多边形窗口的线裁剪的本质特征出发(忽略了整体性?),借鉴了区域编码技术,实现了多边形裁剪算法稳定性和效率上的提高。

2006白晨. 一种任意多边形的裁剪算法

  1. 裁剪定义:从图形中识别出区域内外部分的过程
  2. 计算机速度需求:对于要求图形更新速度的情况下,一旦计算时间的延迟超过了容忍的程度,则失去了工程意义
  3. 二维裁剪
    • 判断是否线段裁剪窗口相交,充分必要条件是线段中有点在裁剪窗口内部。实际计算机工程中不可能通过判断线段中所有的点的情况,这样极大的影响算法效率和精度。
    • 曲线可以通过折线段进行拟合
  4. 不带环多边形之间的裁剪过程
    • 数据结构
    // 各交点的信息:其他被裁剪多边形为S1,裁剪窗口为S2
    struct dot{
    	double x;// 坐标
    	double y;
    	
    	double t1;// 交点在S1上的位置参数
    	double t2;// 交点在S2上的位置参数
    	int l1;// 标记交点在S1上的哪条线段
    	int l2;// 标记交点在S2上的哪条线段
    	int used;// 标记交点在原顶点序列中是否已经使用
    }
    
    • 求裁剪多边形和裁剪窗口的交点:依次取出组成S1和S2边界对各线段两两相交(暴力?),通过各线段的参数方程计算结果,如方程无解,则两线段不相交,如果有解,则求出交点,并将所有的交点按照dot结构放入一个有效交容器vector中
    • 多边形边界重合的情况:当线段和多边形两条边界的交点重合时(即多边形两条边界的交点在线段上),如多边形的两条边界都在线段同侧,则有效交点数量为2,如多边形的两条边界分别在线段不同侧,则有效交点数为1.当线段和多边形边界重合时,如与重合线段相邻的两条多边形边界在重合线段同一侧,则有效交点为1,如与重合线段相邻的两条多边形边界在重合线段不同侧,则有效交点为2。计算有效交点的目的是为了判断点P0是否在多边形S内部,如有小交点数是奇数,则P0在多边形S内部,如有效交点数是偶数,则P0在多边形外部。
      在这里插入图片描述
    • 求被裁剪多边形和裁剪窗口相交后的基本线段:将交点分别插入被裁剪多边形S1和裁剪窗口多边形S2中,再分别对于两个点序列进行线段区分(两个多边形由多个顶点和两个交点形成的闭合区域),如下S1: G → B → C → K G \rightarrow B \rightarrow C \rightarrow K GBCK K → D → E → L K \rightarrow D \rightarrow E \rightarrow L KDEL L → F → M L \rightarrow F \rightarrow M LFM M → A → G M \rightarrow A \rightarrow G MAG,而S2为 G → H → I → J → D G \rightarrow H \rightarrow I \rightarrow J \rightarrow D GHIJD K → L K \rightarrow L KL L → M L \rightarrow M LM M → G M \rightarrow G MG
      在这里插入图片描述
    • 从相关线段组中找到与当前线段夹角最小的线段
      在这里插入图片描述
    • 遍历基本线段单元组,寻找裁剪的结果多边形。从基本线段中找一条没有用于组件多边形的线段作为初试线段,用公示求得它的家教最小的相关线段作为下一条线段,若找到下一条线段和初始相同,则结果多边形找到。
    • 判断多边形的内点。通过判断裁剪多边形内一点是否同时在裁剪窗口和被裁剪多边形内部,可以来判定该多边形是否是我们要求的最终裁剪结果。受三点确定一个平面的公理的启发,可以在多边形中取相邻的三个顶点,找到前两个顶点的中点,然后计算这个中点和第三个顶点连接线的中点,那这个点必然是凸多边形内的一点。但假如图形为凹多边形,则有可能此点落到了多边形外部,还需要重新取另外三个相邻顶点,用同样的方法计算内点,直到找到为止。
      在这里插入图片描述
    • 删除不合格的多边形
      • 删除即不在被裁剪多边形内部也不在裁剪窗口内部的多边形
      • 删除被裁剪多边形和裁剪窗口的轮廓多边形
        在这里插入图片描述
    • 最终结果
      在这里插入图片描述

2006付迎春,袁修孝.一种有效的任意多边形裁剪算法


数控系统的工艺融合论文思路

问题

规则

  1. 线裁剪类型
    • 线段和线段
    • 圆弧和圆弧
    • 线段和圆弧

思路(有问题)

  1. 简单判断实体多边形和裁剪图形是否相交(简单的意思是通过低开销的算法进行不精确的判断)
    • 不可能出现裁剪图形完全在内部的情况,因为车床肯定是从边界开始加工的
    • 如果裁剪图形完全在外部,没有相,根本不需要加工
    • 思路1:静态区域编码方式,如Cohen-Sutherland算法。
    • 思路2:取裁剪图形和实体图形的最值顶点( x m i n 、 x m a x 、 y m i n 、 y m a x x_{min}、x_{max}、y_{min}、y_{max} xminxmaxyminymax),判断是否相交 ( x m i n , y m i n ) ≤ ( x , y ) ≤ ( x m i n , y m i n ) (x_{min}, y_{min}) \leq (x,y) \leq (x_{min}, y_{min}) (xmin,ymin)(x,y)(xmin,ymin)
    • 上面两种思路均无法完全判断,因为存在裁剪后的实体图形的被裁剪区域包含新的裁剪图形的情况
      在这里插入图片描述
  2. 判断相交
    • 思路1:判断实体多边形节点是否和裁剪多边形有交点(核心是判断是否有顶点在裁剪多边形内)
      • 斜向切割: ( x m i n , y m i n ) ≤ ( x , y ) ≤ ( x m a x , y m a x ) (x_{min}, y_{min}) \leq (x,y) \leq (x_{max}, y_{max}) (xmin,ymin)(x,y)(xmax,ymax)&&将 ( x , y ) (x,y) (x,y)带入线段判断是否在下方
      • 矩形切割: ( x m i n , y m i n ) ≤ ( x , y ) ≤ ( x m a x , y m a x ) (x_{min}, y_{min}) \leq (x,y) \leq (x_{max}, y_{max}) (xmin,ymin)(x,y)(xmax,ymax)
      • 圆弧切割: ( x m i n , y m i n ) ≤ ( x , y ) ≤ ( x m a x , y m a x ) (x_{min}, y_{min}) \leq (x,y) \leq (x_{max}, y_{max}) (xmin,ymin)(x,y)(xmax,ymax)&&将 ( x , y ) (x,y) (x,y)带入圆弧判断是否在下方
      • 横向/斜向螺纹切割:相当于给一个线段边界属性的更改(大螺纹如何处理?),判断螺纹的切割是否属于一条实体多边形的边界
      • ( x m i n , y m i n ) ≤ ( x , y ) ≤ ( x m i n , y m i n ) (x_{min}, y_{min}) \leq (x,y) \leq (x_{min}, y_{min}) (xmin,ymin)(x,y)(xmin,ymin)这是一种包装盒的思想,来源于《2002陆国栋,邢世海,彭群生. 基于顶点编码的多边形窗口线裁剪高效算法》,衍生于编码裁剪算法
      • 这个思想无法解决实体多边形顶点不在图形内,但是两个顶点连接成的线段穿过裁剪图形的情况 ,必须处理线段问题
  3. 边界遇到节点走路的贪心策略:
    • 实体多边形边界线段逆时针走。
    • 通过上一条线段和本线段的x与y的增减性判断线段走向
      • 若判断为x增,则遇到交点,优先向y增的方向走,y不增,其次再向x增的方向走
      • 若判断为y增,则遇到交点,优先向x减的方向走,x不减 ,其次再向y增的方向走
        在这里插入图片描述

思路2

  1. 判断是否含有交点
    • 快速排斥

特殊问题

  1. 交点是顶点的情况
  2. 被裁剪直线与窗口的某一边重合

idea

  1. 边所属区分
    • 原理:两个多边形使用单链表连接,插入点时区分插入边的所属,实多边形是顺时针,裁剪多边形用逆时针。在按照实多边形的边开始走,碰见裁剪多边形就按照裁剪多边形走,再碰见实体多边形就走实体多边形。即实体多边形和裁剪多边形交换走,最后形成闭环即可。主要点是顶点表示其顺时针到下一个顶点的边的所属
    • 问题:边重合后的问题,起始点被裁剪掉的问题
    • 本质:每次的进点和出点是一次完整的边裁剪
  2. 各种裁剪算法思路
    • 斜率判断:在被裁剪直线的延长线上取一基准点,然后求多边形裁剪窗口上的每一顶点到该点连线的斜率,从而通过判断被裁剪直线斜率是否在该边两顶点到基准点连线斜率之间,来判定直线与边的关系。
    • 交点判断:用参数法求交得出线段及其延长线与多边形各边的交点,然后判断交点是否是有效交点,并根据参数值排序,去掉重复的交点,最后判断以相邻交点为端点的线段的中点是否可见,若是,则此线段可见,若不是,则不可见。

线裁剪算法

用于多边形裁剪中线段求交点


少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
不如点赞·收藏·关注一波


🚩点此跳转到首行↩︎

参考博客

  1. 如何判别凹多边形
  2. 多边形裁剪一:Sutherland-Hodgman算法
  3. Greiner-Hormann的改进
  4. 裁剪算法——中点分割算法/Liang-Barsky算法
  5. 图形裁剪——二维裁剪+三维裁剪+Sutherland-Cohen裁剪算法+中点分割算法
  6. 图形学初步–裁剪算法之Liang-Barsky算法
  7. 图形学初步–裁剪算法之Liang-Barsky算法
  8. 待定引用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/424745.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三十一天 Linux介绍和基础命令

目录 1.前言 1.1 什么是Linux 1.2 为什么要学Linux 1.3 学完Linux能干什么 2.Linux简介 2.1 主流操作系统 2.2 Linux发展历史 3. Linux安装 3.1 安装方式介绍 3.2 安装VMware 3.3 安装Linux 3.4 网卡设置 3.5 安装SSH连接工具 3.6 Linux目录结构 4.Linux常用命令…

洛谷P8772 [蓝桥杯 2022 省 A] 求和 C语言/C++

[蓝桥杯 2022 省 A] 求和 题目描述 给定 nnn 个整数 a1,a2,⋯,ana_{1}, a_{2}, \cdots, a_{n}a1​,a2​,⋯,an​, 求它们两两相乘再相加的和&#xff0c;即 Sa1⋅a2a1⋅a3⋯a1⋅ana2⋅a3⋯an−2⋅an−1an−2⋅anan−1⋅anSa_{1} \cdot a_{2}a_{1} \cdot a_{3}\cdotsa_{1} \cd…

SpringCloud学习(五)——Nacos配置管理

文章目录1. Nacos实现配置管理2. 微服务拉取配置2.1 拉取优先级2.2 导入依赖2.3 添加注解2.4 配置热更新3. 使用 ConfigurationProperties3.1 使用注解3.2 测试4. 多环境共享配置4.1 添加依赖4.2 配置文件4.3 更改属性4.4 测试4.5 配置优先级1. Nacos实现配置管理 当微服务部署…

【测试面试】吐血整理,大厂测试开发岗面试题(1~4面),拿下年40w...

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 自动化测试面试题&am…

scConverter 文档转换 DLL / SDK 2023.3.21 Crack

scConverter 转换 DLL / SDK scConverter 是一个DLL&#xff0c;可以将PDF、DWF、Gerber、CGM、TIFF、CALS、PLT、PNG和JPEG文件转换为大量输出格式。可用的输出格式列表包括Adob​​e PDF、PDF/A、DXF、DWF、CALS、TIFF、PLT和PNG。您将在下面找到所有可用输入和输出格式的完整…

计算机算法设计与分析(第5版)PDF

《计算机算法设计与分析&#xff08;第5版&#xff09;》是2018年电子工业出版社出版的图书&#xff0c;作者是王晓东。 整本书的结构是&#xff1a;先介绍算法设计策略思想&#xff0c;然后从解决经典算法问题来学习&#xff0c;通过实践的方式去学习算法。 网络上许多的算法…

天梯赛-模拟赛-4.16

L2-041 插松枝 人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上&#xff0c;做成大大小小的松枝。他们的工作流程&#xff08;并不&#xff09;是这样的&#xff1a; 每人手边有一只小盒子&#xff0c;初始状态为空。 每人面前有用不完的松枝干和一个推送器&#x…

【鸿蒙应用ArkTS开发系列】- Web组件使用讲解

目录 一、Web组件介绍 二、创建组件 权限列表 三、设置样式和属性 四、添加事件和方法 五、访问本地Html 1、本地html文件创建 2、本地html文件加载 2、JS对象注入&#xff0c;Html使用JS对象调用客户端方法 3、客户端调用本地Html网页中的JS方法 使用鸿蒙的ArkUI框架…

Lesson 10.1 超参数优化与枚举网格的理论极限和随机网格搜索 RandomSearchCV

文章目录一、超参数优化与枚举网格的理论极限1. 超参数优化 HPO&#xff08;HyperParameter Optimization&#xff09;2. 网格搜索的理论极限与缺点3. 建立 benchmark&#xff1a;随机森林中枚举网格搜索的结果二、随机网格搜索 RandomizedSearchCV1. 基本原理2. 随机网格搜索的…

使用chatgpt实现微信聊天小程序(秒回复),github开源(附带链接)

文章目录前言效果展示原理说明服务器端代码说明微信小程序代码说明代码链接总结前言 我在前一段时间突发奇想&#xff0c;就使用java来调用chatgpt的接口&#xff0c;然后写了一个简单小程序&#xff0c;也上了热榜第一&#xff0c;java调用chatgpt接口&#xff0c;实现专属于…

select 排序qsort排序

目录 1.希尔排序的时间复杂度 3.有技巧的选择排序&#xff1a;堆排序 4.排序的种类 5.直接插入排序和冒泡排序 6.快速排序 7.希尔排序 堆排序 和快排的区别 8.为什么相遇位置一定比key小 9.快排的优化 11.快排递归写法的不足 12.快排的非递归解法 1.希尔排序的时间复杂…

C++11新特性(上)

357089 文章目录1. 统一的列表初始化1.1 &#xff5b;&#xff5d;初始化1.2 std::initializer_list2. decltype3. 右值引用和移动语义3.1 左值引用和右值引用3.2 左值引用与右值引用比较3.3 右值引用使用场景和意义3.4 右值引用引用左值及更深入的使用场景3.5 完美转发4. 新的…

“编程式 WebSocket” 实现简易 online QQ在线聊天项目

目录 一、需求分析与演示 1.1、需求分析 1.2、效果演示 二、客户端、服务器开发 2.1、客户端开发 2.2、服务器开发 一、需求分析与演示 1.1、需求分析 需求&#xff1a;实现一个 online QQ在线聊天项目&#xff0c;当用户登录上自己的账号后&#xff0c;将会显示在线&…

我用nodejs和electron实现了一个简单的聊天软件-----chat 开源

翎&#x1f3a5;项目演示地址 &#x1f517;https://www.bilibili.com/video/BV1Fg4y1u76d/ 希望观众老爷给个免费的三连支持一下新人up主 ♻️项目基本介绍 翎是基于electron(vue2)和nodejs实现的简单聊天软件,其中用websocket和http进行通讯传递,数据库使用了mysql数据库,…

二进制插入与查找组成一个偶数最接近的两个素数

二进制插入 链接&#xff1a;二进制插入_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a;给定两个32位整数n和m&#xff0c;同时给定i和j&#xff0c;将m的二进制数位插入到n的二进制的第j到第i位,保证n的第j到第i位均为零&#xff0c;且m的二进制位数小于等于i-j1&#xff…

Qt Quick - Popup

Qt Quick - Popup使用总结一、概述二、Popup 的布局三、弹出分级四、弹出定位五、定制化一、概述 Popup是类似弹出式用户界面控件的基本类型。它可以与Window或ApplicationWindow一起使用。 import QtQuick.Window 2.2import QtQuick.Controls 2.12ApplicationWindow {id: win…

力推美团企业版 美团究竟意欲何为?

已经拥有930万活跃商家的美团公司&#xff0c;正在充分整合自身的“供应链”优势&#xff0c;冲向B端市场。 3月31日&#xff0c;据36氪消息显示&#xff0c;美团将于近期正式上线面向To B市场的业务“美团企业版”&#xff0c;定位企业消费赛道。美团企业版会为企业客户提供消…

ZeroTier 内网穿透

ZeroTier 内网穿透 官网注册账号&#xff0c;创建自己的局域网段, 登录官网 创建网络&#xff1a; 点击创建好的网络&#xff0c;进入设置界面进行设置, 选择 public 模式,点击入设置页面 地址随便选择 说明没有设备链接 下载客户端 &#xff0c;下载 安装客户端&#xf…

高级数据结构与算法 | 三元搜索树(Ternary Search Tree)

文章目录TernarySearchTree基本概念介绍原理插入查找删除代码实现TernarySearchTree 基本概念 介绍 Ternary Search Tree&#xff08;三元搜索树&#xff09;&#xff0c;它是由 Bentley 和 Sedgewick 在 1997 年提出的一种基于 Trie 的思想改良的一种数据结构&#xff0c;其…

【GCU体验】基于PyTorch + GCU跑通ResNet50模型并测试GCU性能

一、环境 地址&#xff1a;启智社区:https://openi.pcl.ac.cn/ 二、计算卡介绍 云燧T20是基于邃思2.0芯片打造的面向数据中心的第二代人工智能训练加速卡&#xff0c;具有模型覆盖面广、性能强、软件生态开放等特点&#xff0c;可支持多种人工智能训练场景。同时具备灵活的可…