一、数字微分分析仪(digital differential analyzer, DDA)方法是一种线段扫描转换算法。在一个坐标轴上以单位间隔对线段取样,从而确定另一个坐标轴上最靠近线路径的对应整数值。主要是根据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。
算法过程:
输入线段两个端点的像素位置,端点位置间的水平和垂直差赋给参数dx和dy。绝对值大的参数确定steps的值。从像素位置(xBegin,yBegin)开始,确定沿线段生成下一个像素位置的每一步所需的偏移量,并循环上述过程setps次。假如dx的绝对值大于dy的绝对值,且xBegin小于xEnd,那么x和y方向的增量值分别为1和m。假如x方向的变化较大,但xBegin大于xEnd,那么就采用减量-1和-m来生成线段上的每个点。在其他情况下,y方向使用单位增量(或减量),x方向使用1/m的增量(或减量)。
1 inline int Round(const float a) { return static_cast (a + 0.5); } 2 3 void LineDDA(int xBegin, int yBegin, int xEnd, int yEnd) 4 { 5 int dx = xEnd - xBegin; 6 int dy = yEnd - yBegin; 7 int steps, k; 8 9 float xIncrement, yIncrement;10 float x = static_cast (xBegin);11 float y = static_cast (yBegin);12 13 if (fabs(dx) > fabs(dy)) {14 steps = fabs(dx);15 }16 else {17 steps = fabs(dy);18 }19 20 xIncrement = static_cast(dx) / static_cast (steps);21 yIncrement = static_cast (dy) / static_cast (steps);22 23 glBegin(GL_POINTS);24 25 for (k = 0; k < steps; ++k) {26 x += xIncrement;27 y += yIncrement;28 glVertex2i(round(x), round(y));29 }30 glEnd();31 }
二、Bresenham画线算法是一种精确而有效的光栅线生成算法,该算法仅仅使用了增量整数计算。
在取样位置,用和来标识两个像素与数学上线路径的垂直偏移。在像素列位置处的直线上的坐标可计算为
那么
和
要确定两像素中哪一个更接近线路径,需测试两个像素偏移的差:
令
则
相减可得到
因
算法过程:
时的Bresenham画线算法:
1.输入线段的两个端点,并将左端点存储在(xBegin, yBegin)中;
2.将(xBegin, yBegin)装入帧缓存,画出第一个点;
3.计算常量、、和,并得到决策参数的第一个值:
4.从开始,在沿线路径的每个处,进行下列检测:
如果,下一个要绘制的点是,并且
否则,下一个要绘制的点是,并且
5.重读步骤4,共次;
1 void LineBresenham(int xBegin, int yBegin, int xEnd, int yEnd) 2 { 3 int dx = fabs(xEnd - xBegin); 4 int dy = fabs(yEnd - yBegin); 5 6 7 int p = 2 * dy - dx; 8 int two_dy = 2 * dy; 9 int two_dy_minus_dx = 2 * (dy - dx);10 int x, y;11 int yName;12 13 if (xBegin > xEnd) {14 yName = yBegin - yEnd;15 x = xEnd;16 y = yEnd;17 xEnd = xBegin;18 }19 else {20 yName = yEnd - yBegin;21 x = xBegin;22 y = yBegin;23 }24 while (x <= xEnd) {25 glBegin(GL_POINTS);26 glVertex2i(x, y);27 glEnd();28 29 if (dx == 0 && y < yEnd) {30 y++;31 continue;32 }33 if (p < 0) {34 x++;35 p += two_dy;36 }37 else if (yName > 0) {38 y++;39 x++;40 p += two_dy_minus_dx;41 }42 else if (yName < 0) {43 y--;44 x++;45 p += two_dy_minus_dx;46 }47 }48 }