闻心阁

一蓑烟雨看苍生,半壶浊酒笑红尘

直线剪裁算法-Cohen-Sutherland

2011-06-02 约 1 分钟读完 搬砖秘籍

计算机图形学,这次说的是二维图形的剪裁,接下来将说明两种直线剪裁算法,今天说的是Cohen-Sutherland直线剪裁算法。

还是老规矩,只放代码,不讲原理,想要看Cohen-Sutherland原理的人请绕行~

代码如下:

//下面是进行c-s裁剪的函数集合*****

//对某点位置进行编码,有种情况

unsigned char code(CPoint rect1,CPoint rect2,float x,float y)

{

//裁剪窗体里面,

unsigned char c=0;

//裁剪窗体左面,

if(((int)(x+0.5))<((int)(0.5+rect1.x)))

c=c|1;

//裁剪窗体右边,

else if(((int)(x+0.5))>((int)(0.5+rect2.x)))

c=c|2;

//裁剪窗体上面,

if(((int)(y+0.5))<((int)(0.5+rect1.y)))

c=c|4;

//裁剪窗体下面,

else if(((int)(y+0.5))>((int)(0.5+rect2.y)))

c=c|8;

return c;

}

void S5GraphLine::C_S(CPoint p1,CPoint p2,CDC *pDC)

{//p1,p2为传入的矩形剪裁框的左上和右下的点

int index=m_Lines.size();

for (int i=0;i<index;i++)

{

unsigned char c1,c2,c;

float x,y,wx,wy;

//对第一点进行编码

c1=code(p1,p2,m_Lines.at(i).m_pntStart.x,m_Lines.at(i).m_pntStart.y);

//对第二点进行编码

c2=code(p1,p2,m_Lines.at(i).m_pntEnd.x,m_Lines.at(i).m_pntEnd.y);

while((!(c1==0))||(!(c2==0)))

{//当两个点其中一个的编码不为零就进行循环,

//也就是说有一点不在裁剪窗体里面就进行循环

if(c1&c2)

//当两个点都在裁剪窗体外面时删除这条线段,

//然后结束函数

{

CPoint p(-1,-1);

m_Lines.at(i).m_pntStart=p;

m_Lines.at(i).m_pntEnd=p;

break;

}

else

{

c=c1;

if(c==0) //找出在裁剪窗口外的一点

c=c2;

wx=m_Lines.at(i).m_pntEnd.x-m_Lines.at(i).m_pntStart.x;

wy=m_Lines.at(i).m_pntEnd.y-m_Lines.at(i).m_pntStart.y;

if((c&1)==1)

//如果线段的一部分在窗体左面,

//那么根据窗口左边届的x坐标修计算其y坐标

{

y=m_Lines.at(i).m_pntStart.y+wy*((float)(p1.x)-m_Lines.at(i).m_pntStart.x)/wx;

x=(float)(p1.x);

}

else if((c&2)==2)

//如果线段的一部分在窗体右面,

//那么根据窗口右边届的x坐标修计算其y坐标

{ y=m_Lines.at(i).m_pntStart.y+wy*((float)(p2.x)-m_Lines.at(i).m_pntStart.x)/wx;

x=(float)(p2.x);

}

else if((c&4)==4)

{ x=m_Lines.at(i).m_pntStart.x+wx*((float)(p1.y)-m_Lines.at(i).m_pntStart.y)/wy;

y=(float)(p1.y);

}

else if((c&8)==8)

{ x=m_Lines.at(i).m_pntStart.x+wx*((float)(p2.y)-m_Lines.at(i).m_pntStart.y)/wy;

y=(float)(p2.y);

}

if(c==c1)

{

m_Lines.at(i).m_pntStart.x=x;

m_Lines.at(i).m_pntStart.y=y; c1=code(p1,p2,m_Lines.at(i).m_pntStart.x,m_Lines.at(i).m_pntStart.y);

}

else

{

m_Lines.at(i).m_pntEnd.x=x;

m_Lines.at(i).m_pntEnd.y=y;

c2=code(p1,p2,m_Lines.at(i).m_pntEnd.x,m_Lines.at(i).m_pntEnd.y);

}

}

}

}

}

PS:又搞定一个算法!Cohen-Sutherland呵呵!