//经过多重优化的中点画线算法,输入为线段两端点的坐标值 //该算法经过数学推导,可以处理斜率不存在,斜率为零,斜率为负数,斜率绝对值大于一等各种情况 void Mid_point(const unsigned& x1, const unsigned& y1, const unsigned& x2, const unsigned& y2) { int dx = x2 - x1, dy = y2 - y1; enum Main_ChangeDirection { x, y }; Main_ChangeDirection MainChange; if (abs(dx) >= abs(dy)) MainChange = x; else MainChange = y; if ((MainChange == x && x1 > x2) || (MainChange == y && y1 > y2))//如果在主要变化方向上两点不满足升序排列,则递归调用自身,相当于交换两个点 { Mid_point(x2, y2, x1, y1); return; } initgraph(800, 640); if (dx == 0)//处理斜率不存在的特殊情况 { for (unsigned y = y1; y <= y2; ++y) { putpixel(x1, y, RED); } _getch(); closegraph(); return; } enum trend { Positive, Negative };//用一个枚举变量记录直线的斜率是否大于零,需要对大于零小于零两张情况进行分开考虑 trend k; if (dx * dy >= 0) k = Positive; else k = Negative; int a = -dy, b = dx; if (MainChange == x) { if (k == Positive) { int d = 2 * a + b; int delta1 = 2 * a; int delta2 = 2 * (a + b); for (unsigned x = x1, y = y1; x <= x2; ++x) { putpixel(x, y, BLUE); if (d > 0) { d += delta1; } else { d += delta2; y++; } } } else if (k == Negative) { int d = 2 * a - b; int delta1 = 2 * (a - b); int delta2 = 2 * a; for (unsigned x = x1, y = y1; x <= x2; ++x) { putpixel(x, y, BLUE); if (d > 0) { d += delta1; --y; } else { d += delta2; } } } } else if (MainChange == y) { if (k == Positive) { int d = a + 2 * b; int delta1 = 2 * (a + b); int delta2 = 2 * b; for (unsigned y = y1, x = x1; y <= y2; ++y) { putpixel(x, y, BLUE); if (d > 0) { d += delta1; ++x; } else { d += delta2; } } } else if (k == Negative) { int d = 2 * b - a; int delta1 = 2 * b; int delta2 = 2 * (b - a); for (unsigned y = y1, x = x1; y <= y2; ++y) { putpixel(x, y, BLUE); if (d > 0) { d += delta1; } else { d += delta2; x--; } } } } _getch(); closegraph(); }
注:使用该函数需要头文件<graphics.h>和<conio.h>,前一个头文件不在系统库中,可以直接百度免费下载。