因为最近CSDN上传资源出现问题,无法上传,等可以上传之后再给出下载地址。
源码下载:点我下载
首先讲一下算法的原理:
Sutherland-Hodgeman算法:
基本思想是一次用窗口的一条边裁剪多边形。
考虑窗口的一条边以及延长线构成的裁剪线,该线把平面分成两个部分:可见一侧;不可见一侧。
多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种,
如图:
S、P与裁剪线的位置关系 对于情况(1)仅输出顶点P;情况(2)输出0个顶点;情况(3)输出线段SP与裁剪线的交点I;情况(4)输出线段SP与裁剪线的交点I和终点P
上述算法仅用一条裁剪边对多边形进行裁剪,得到一个顶点序列,作为下一条裁剪边处理过程的输入。
对于每一条裁剪边,只是判断点在窗口哪一侧改变求线段SP与裁剪边的交点的算法。
算法的实现过程还是比较复杂的。
代码过程:
1首先画一个多边形,然后记录边数和边的2个顶点。
2.运行算法。
算法的实现:
-
typedef struct
-
{
-
int x;
-
int y;
-
}Vertex;
-
typedef struct
-
{
-
int xmin;
-
int xmax;
-
int ymin;
-
int ymax;
-
}
-
rectangle;
-
typedef Vertex Edge[2];
-
typedef Vertex VertexArray[MAX];
-
VertexArray InVertexArray;
-
VertexArray OutVertexArray;
-
Edge ClipBoundary[4];
-
rectangle rect1;
-
int InLength;
-
int OutLength;
-
void CClipingView::InitClipBoundary(rectangle rect1)
-
{
-
//InitRectangle();
-
ClipBoundary[0][0].y=YT;
-
ClipBoundary[0][0].x=XL;
-
ClipBoundary[0][1].y=YT;
-
ClipBoundary[0][1].x=XR;
-
ClipBoundary[1][0].x=XR;
-
ClipBoundary[1][0].y=YT;
-
ClipBoundary[1][1].x=XR;
-
ClipBoundary[1][1].y=YB;
-
ClipBoundary[2][0].x=XR;
-
ClipBoundary[2][0].y=YB;
-
ClipBoundary[2][1].x=XL;
-
ClipBoundary[2][1].y=YB;
-
ClipBoundary[3][0].x=XL;
-
ClipBoundary[3][0].y=YB;
-
ClipBoundary[3][1].x=XL;
-
ClipBoundary[3][1].y=YT;
-
}
-
void CClipingView::SutherlandHodgmanPolygonClip(int InLength, VertexArray InVertexArray, int *OutLength, VertexArray OutVertexArray, Edge ClipBoundary)
-
{
-
Vertex *s,*p,I;
-
int j;
-
*OutLength=0;
-
s=&(InVertexArray[InLength-1]);
-
for(j=0;j<InLength;j++)
-
{
-
p=&(InVertexArray[j]);
-
if(Inside(p,ClipBoundary))
-
{
-
if(Inside(s,ClipBoundary))
-
Output(p,OutLength,OutVertexArray);
-
else
-
{
-
Intersect(s,p,ClipBoundary,&I);
-
Output(&I,OutLength,OutVertexArray);
-
Output(p,OutLength,OutVertexArray);
-
}
-
}
-
else
-
if(Inside(s,ClipBoundary))
-
{
-
Intersect(s,p,ClipBoundary,&I);
-
Output(&I,OutLength,OutVertexArray);
-
}
-
s=p;
-
}
-
}
-
bool CClipingView::Inside(Vertex *textVertex, Edge ClipBoundary)
-
{
-
if(ClipBoundary[1].x>ClipBoundary[0].x)//裁剪边为窗口的下边
-
{
-
if(textVertex->y>=ClipBoundary[0].y)
-
return TRUE;
-
}
-
else
-
if(ClipBoundary[1].x<ClipBoundary[0].x)//裁剪边为窗口的上边
-
{
-
if(textVertex->y<=ClipBoundary[0].y)
-
return TRUE;
-
}
-
else
-
if(ClipBoundary[1].y>ClipBoundary[0].y)//裁剪边为窗口的右边
-
{
-
if(textVertex->x<=ClipBoundary[0].x)
-
return TRUE;
-
}
-
else
-
if(ClipBoundary[1].y<ClipBoundary[0].y)//裁剪边为窗口的左边
-
{
-
if(textVertex->x>=ClipBoundary[0].x)
-
return TRUE;
-
}
-
return FALSE;
-
}
-
void CClipingView::Intersect(Vertex *s, Vertex *p, Edge ClipBoundary, Vertex *I)
-
{
-
if(ClipBoundary[0].y==ClipBoundary[1].y)
-
{
-
I->y=ClipBoundary[0].y;
-
I->x=s->x+(ClipBoundary[0].y-s->y)*(p->x-s->x)/(p->y-s->y);
-
}
-
else
-
{
-
I->x=ClipBoundary[0].x;
-
I->y=s->y+(ClipBoundary[0].x-s->x)*(p->y-s->y)/(p->x-s->x);
-
}
}
-
void CClipingView::All_SutherlandHodgmanPolygonClip()
-
{
-
int i;
-
InitClipBoundary(rect1);
-
SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[0]);//裁剪边为下
-
InLength=OutLength;
-
for(i=0;i<=OutLength-1;i++)
-
{
-
InVertexArray[i].x=OutVertexArray[i].x;
-
InVertexArray[i].y=OutVertexArray[i].y;
-
}
-
OutLength=0;
-
SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[1]);//裁剪边为右
-
InLength=OutLength;
-
for(i=0;i<=OutLength-1;i++)
-
{
-
InVertexArray[i].x=OutVertexArray[i].x;
-
InVertexArray[i].y=OutVertexArray[i].y;
-
}
-
OutLength=0;
-
SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[2]);//裁剪边为上
-
InLength=OutLength;
-
for(i=0;i<=OutLength-1;i++)
-
{
-
InVertexArray[i].x=OutVertexArray[i].x;
-
InVertexArray[i].y=OutVertexArray[i].y;
-
}
-
OutLength=0;
-
SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[3]);
-
InitPloygon2();
-
//Invalidate();
-
}
其中只给出了一些核心的算法和数据结构。
想要了解更多可以下载我的源码时时的运行或进行DeBug来查看代码的具体情况。
如果有什么不多的地方还请指出。让我们一起学习,一起进步。谢谢。