直线剪裁算法-Liang-Barsky
接着上面的计算机图形学,二维图形的剪裁,还是直线剪裁算法,今天说的是Liang-Barsky直线剪裁算法。
还是老规矩,只放代码,不讲原理,想要看Liang-Barsky原理的人请绕行~
代码如下:
//裁剪测试函数int ClipTest(double u,double v,double *tmax,double *tmin)
{//顺序左右下上
double t;int ReturnValue=TRUE;
if(u<0.0)//外部到内部,计算起点处的tmax
{
t=v/u;
if(t>*tmin)
ReturnValue=FALSE;
else if(t>*tmax)
*tmax=t;
}
else
{
if(u>0.0)//内部到外部,计算终点处的tmin
{
t=v/u;
if(t<*tmax)
ReturnValue=FALSE;
else if(t<*tmin)
*tmin=t;
}
else//平行于窗口边界的直线
{
if(v<0.0)//直线在窗口外可直接删除
ReturnValue=FALSE;
}
}
return(ReturnValue);
}
//裁剪函数
void S5GraphLine::L_B(CPoint p1,CPoint p2,CDC *pDC)
{
double x1;
double y1;
double x2;
double y2;
int index=m_Lines.size();
for(int i=0;i<index;i++)
{
x1=m_Lines.at(i).m_pntStart.x;
x2=m_Lines.at(i).m_pntEnd.x;
y1=m_Lines.at(i).m_pntStart.y;
y2=m_Lines.at(i).m_pntEnd.y;
double tmax,tmin,dx,dy;
dx=x2-x1;dy=y2-y1;tmax=0.0,tmin=1.0;
//窗口边界的左、右、下、上顺序裁剪直线
//n=,左边界u1=-△x,v1=x1-wxl
if(ClipTest(-dx,x1-p1.x,&tmax,&tmin))
{
//n=,右边界u2=△x,v2=wxr-x1
if(ClipTest(dx,p2.x-x1,&tmax,&tmin))
{
//n=,下边界u3=-△y,v3=y1-wyb
if(ClipTest(-dy,y1-p1.y,&tmax,&tmin))
{
//n=,上边界u4=△y,v4=wyt-y1
if(ClipTest(dy,p2.y-y1,&tmax,&tmin))
{
if(tmin<1.0)//判断直线的终点
{
x2=x1+tmin*dx;//重新计算直线端点
y2=y1+tmin*dy;//x=x1+t(x2-x1)格式
int a=x2;
int b=y2;
CPoint p(a,b);
m_Lines.at(i).m_pntEnd=p;
}
if(tmax>0.0)//判断直线的起点
{
x1=x1+tmax*dx;
y1=y1+tmax*dy;
int a=x1;
int b=y1;
CPoint p(a,b);
m_Lines.at(i).m_pntStart=p;
}
}
else
{
CPoint a(-1,-1);
m_Lines.at(i).m_pntStart=a;
m_Lines.at(i).m_pntEnd=a;
}
}
else
{
CPoint a(-1,-1);
m_Lines.at(i).m_pntStart=a;
m_Lines.at(i).m_pntEnd=a;
}
}
else
{
CPoint a(-1,-1);
m_Lines.at(i).m_pntStart=a;
m_Lines.at(i).m_pntEnd=a;
}
}
else
{
CPoint a(-1,-1);
m_Lines.at(i).m_pntStart=a;
m_Lines.at(i).m_pntEnd=a;
}
}
}
声明:
使用的时候请直接调用L_B函数(即第二个函数)即可,第一个函数是在第二个函数中调用的PS:又搞定一个算法!Liang-Barsky呵呵!