先前弄STM32驱动LCD时曾见Bresenham算法,最近学习opencv时应需要特意学习了此算法(参考了《计算机图形学》),个人认为此算法的精髓在于得到一个决策参数,来判断下一个像素点的位置,从而避免了大量的浮点运算,提高了程序的运行速度。下面是画线的代码:
画线算法:
void BresenhamLine(int x0, int y0, int xe, int ye, vector<Point2i>& pointbuf)
{
int temp;
int dx = abs(xe - x0);
int dy = abs(ye - y0);
int cdx, cdy;
/***********斜率大于1*******/
if (dx < dy)//坐标转换
{
swap_int(&x0, &y0);
swap_int(&xe, &ye);
cdx = dy;
cdy = dx;
}
else {
cdx = dx;
cdy = dy;
}
/***************************/
int count = cdx,
sign = 1;//斜率为负标志位
if (x0 > xe){
swap_int(&x0, &xe);
swap_int(&y0, &ye);
}
if (y0 > ye) {
x0 = xe;
y0 = ye;
sign = -1;
}
int p = 2 * cdy - cdx;
if (dy>dx)//是否进行了坐标转换
SetPoint(y0, x0, pointbuf);
else
SetPoint(x0, y0, pointbuf);
while (count--){
x0 += sign;
if (p < 0)
p += 2 * cdy;
else{
y0++;
p += 2 * cdy - 2 * cdx;
}
if (dy>dx)//是否进行了坐标转换
SetPoint(y0, x0, pointbuf);
else
SetPoint(x0, y0, pointbuf);
}
}
void circle(int x0, int y0, int r, vector<Point2i>& pointbuf)
{
int p = 1 - r;
int x = 0, y = r;
SetPoint(x0, y + y0, pointbuf);
SetPoint(x0, y0 - y, pointbuf);
SetPoint(x0 - y, y0, pointbuf);
SetPoint(x0 + y, y0, pointbuf);
while (x < y)
{
x++;
if (p < 0)
p += 2 * x + 1;
else{
p += 1 + 2 * (x - y);
y--;
}
CirclePlot(x, y, x0, y0, pointbuf);
}
}