直线剪裁算法-Cohen-Sutherland
计算机图形学,这次说的是二维图形的剪裁,接下来将说明两种直线剪裁算法,今天说的是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呵呵!