您的位置:首页 > 理论基础

计算机图形学(六)多边形裁剪Sutherland-Hodgeman算法讲解与源代码

2017-04-21 11:24 393 查看
因为最近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来查看代码的具体情况。

如果有什么不多的地方还请指出。让我们一起学习,一起进步。谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息