我们可以考虑有下面的多边形
黑色边框就是区域就是裁剪下来的多边形区域,我们可以将裁剪区域与多边形区域的端点看作有效边表,显然对于左边界来说我们是要选取边界x值大的点作为新的多边形的边界,对于右边界我们是要选择x值小的点作为多边形的边界,这样我们就可以将整个问题转换成有效边表选取的问题,我们可以简要的分析对于矩形裁剪区域是可以实现这种裁剪方法的,但是对于别的裁剪区域呢?比如五角星裁剪区域,显然这种方法仍然是适用的
如何得到新边表呢?边表中的点一个是左界一个是右界两两能够配对,在分别两个边表内部将两两能够配对的点分为一组,然后按组别进行比较来得出新边表中的点可以使用哪些点。因为待裁剪区域的分成两两配对的组别,裁剪窗口的也分成两两配对,每比较一组的时候其实我们是很简单的,同时因为在选取时可能有一组点表示的区域较大,根据这一组点比较并不能判定其中没有其他的边界点了,此时我们就需要保留了,然后因为另一组的关系已经明了,所以可以换下一组点继续与当前点进行比较。依次进行下去,最后就能得到一个新的边表。
得到新边表的大致过程如下:
指定位置边表如下:
x1、x_1的相对位置反应相对大小,实际上在各自的链表存储时并没有这样的关系。
我们每一次将上面配对的两点与下面配对的两点进行抉择确定出一个新的边表
依照这种方法我们可以确定出整个裁剪出的多边形。
而且每一次判断待裁剪多边形边表的一个始点与终点这两点与裁剪窗口的一个始点与终点的相对位置,相对位置只有以下几种:
使用新边表绘制出的多边形就是使用裁剪你窗口裁剪指定多边形得到的裁剪多边形。
关键代码:
struct ListNode * t1 = list1[i].next;
struct ListNode* t2 = list2[i].next;
struct ListNode* t3 = &list3[i];
while (t1 != NULL&&t2!=NULL){
struct ListNode* t11 = t1->next;
struct ListNode* t22 = t2->next;
if (t11->data.start < t2->data.start) {
t1 = NULL;
continue;
}
else {
if (!(t1->data.start > t22->data.start)) {
t3->next = (struct ListNode*)malloc(sizeof(struct ListNode));
t3 = t3->next;
t3->next = NULL;
t3->data.start = t1->data.start > t2->data.start ? t1->data.start : t2->data.start;
t3->next = (struct ListNode*)malloc(sizeof(struct ListNode));
t3 = t3->next;
t3->next = NULL;
t3->data.start = t11->data.start > t22->data.start ? t22->data.start : t11->data.start;
if (t3->data.start == t22->data.start) {
if (t22->next != NULL) {
t2 = t22->next;
t22 = t2->next;
}
else {
t2 = NULL;
continue;
}
}
else {
if (t11->next != NULL) {
t1 = t11->next;
t11 = t1->next;
}
else {
t1 = NULL;
continue;
}
}
}
else {
if (t22->next == NULL) {
t2 = NULL;
continue;
}
else {
t2 = t22->next;
t22 = t2->next;
}
}
}
}