实验要求: 实现直线段生成的两种方法: 1) 数值微分法 和 2) 中点Bresenham算法。用户用鼠标点击两个点,两个点都确定后,利用直线段的绘制算法绘制两个点之间的一条直线段。本文章仅涉及算法的具体函数实现。
注:startp, 和endp 是线段的两个端点(包含x轴坐标和y轴坐标),fillOnePixel() 函数用来绘制一个像素。实现直线生成算法的绘直线函数:
void drawLine(CPoint startp, CPoint endp){}
数值微分法:
void drawLine(CPoint startp, CPoint endp)
{
double increx, increy, x, y, length;
if (abs(endp.x - startp.x) > abs(endp.y - startp.y))
{
length = abs(endp.x - startp.x);
}
else
{
length = abs(endp.y - startp.y);
}
increx = (endp.x - startp.x) / length;
increy = (endp.y - startp.y) / length;
x = startp.x;
y = startp.y;
for (int i = 1; i <= length; i++)
{
fillOnePixel(x, y);
x += increx;
y += increy;
}
}
中点Bresenham算法:
void drawLine(CPoint startp, CPoint endp)
{
int dx = endp.x - startp.x;
int dy = endp.y - startp.y;
int ux = ((dx > 0) << 1) - 1;
int uy = ((dy > 0) << 1) - 1;
int x = startp.x, y = startp.y, eps = 0;
dx = abs(dx);
dy = abs(dy);
if (dx > dy)
{
for (x = startp.x; x != endp.x; x += ux)
{
fillOnePixel(x,y);
eps += dy;
if ((2 * eps) >= dx)
{
y += uy;
eps -= dx;
}
}
}
else
{
for (y = startp.y; y != endp.y; y += uy)
{
fillOnePixel(x, y);
eps += dx;
if ((2 * eps) >= dy)
{
x += ux;
eps -= dy;
}
}
}
}
运行效果: