这个算法的效率比前面提到的Cohen-Sutherland要高
思路是把直线表示为参数方程形式,
x= x1+udx
y = y1+udy
由xmin<x<xmax
ymin<y<ymax
可以得到四个不等式,简化成同一个形式up<q 当p不等于0的时候,可以算出来u与边界的交点,p等于0的时候,左边等于0,只需简单的判断q的正负。
然后求直线和边界以及边界延长线的四个交点,u1取由外往内的两个交点的u值以及0的最大值
u2取由内往外的两个交点和1的最小值,得到的u1和u2就是直线两端点的坐标。
更新u的函数如下:
float u1 = 0;
float u2 = 1;
bool ClipT(int p, int q)
{
float r;
if (p < 0)
{
r = (float)q / p;
if (r > u2)
return false;
if (r > u1)
u1 = r;
}
else if (p > 0)
{
r = (float)q / p;
if (r < u1)
return false;
if (r < u2)
u2 = r;
}
else
return q >= 0;
return true;
}
画图函数如下:
代码中区域范围为(200,200)到(400,400)
void LB_lineClip(Point p1, Point p2)
{
Graphics g = this.CreateGraphics();
Pen p = new Pen(Brushes.Black);
int dx = p2.X - p1.X, dy = p2.Y - p1.Y;
if(ClipT(-dx,p1.X-200))
if(ClipT(dx,400-p1.X))
if(ClipT(-dy,p1.Y-200))
if(ClipT(dy,400-p1.Y))
g.DrawLine(p, p1.X+u1*dx,p1.Y+u1*dy,p1.X+u2*dx,p1.Y+u2*dy);
}