直线剪裁算法-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呵呵!