闻心阁

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

直线剪裁算法-Liang-Barsky

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

接着上面的计算机图形学,二维图形的剪裁,还是直线剪裁算法,今天说的是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呵呵!