阅读《计算机图形学》接触到bresenham画线算法,该算法的核心是用精确的化简后结果衡量每次递增单元格后另一个方向要不要相应递增,书中列举了斜率m绝对值小于1的情况算法,本文完善书中代码使之适配所有斜率情况。
代码如下:
#include
#include
#include
void drawpixel(int x, int y){
HDC hdc = GetWindowDC(GetDesktopWindow());
SetPixel(hdc, x, y, RGB(255, 0, 0));
}
void lineBres(int x0, int y0, int xEnd, int yEnd){
int dx = abs(xEnd - x0);
int dy = abs(yEnd - y0);
int x, y;
if (dx == 0)
{
int interval = (yEnd > y0) ? 1 : -1;
x = x0, y = y0;
drawpixel(x, y);
while (y != yEnd)
{
y += interval;
drawpixel(x, y);
}
}
else if (dy == 0)
{
int interval = (xEnd > x0) ? 1 : -1;
x = x0, y = y0;
drawpixel(x, y);
while (x != xEnd)
{
x += interval;
drawpixel(x, y);
}
}
else
{
bool klower1 = (dy <= dx);
if (klower1)
{
int p = 2 * dy - dx;
int twody = 2 * dy;
int twodyminusdx = 2 * (dy - dx);
if (xEnd < x0)
{
//交换首尾
x0 = xEnd - x0;
xEnd = xEnd - x0;
x0 = xEnd + x0;
y0 = yEnd - y0;
yEnd = yEnd - y0;
y0 = yEnd + y0;
}
x = x0;
y = y0;
drawpixel(x, y);
while (x < xEnd)
{
x++;
if (p < 0)
{
drawpixel(x, y);
p += twody;
}
else
{
y += (yEnd > y0) ? 1 : -1;
drawpixel(x, y);
p += twodyminusdx;
}
}
}
else
{
int p = 2 * dx - dy;
int twodx = 2 * dx;
int twodxminusdy = 2 * (dx - dy);
if (yEnd < y0)
{
//交换首尾
x0 = xEnd - x0;
xEnd = xEnd - x0;
x0 = xEnd + x0;
y0 = yEnd - y0;
yEnd = yEnd - y0;
y0 = yEnd + y0;
}
x = x0;
y = y0;
drawpixel(x, y);
while (y < yEnd)
{
y++;
if (p < 0)
{
drawpixel(x, y);
p += twodx;
}
else
{
x += (xEnd > x0) ? 1 : -1;
drawpixel(x, y);
p += twodxminusdy;
}
}
}
}
}
void main(){
//dy==0
lineBres(20, 10, 300, 10);
lineBres(300, 10, 20, 10);
//dx==0
lineBres(20, 10, 20, 300);
lineBres(20, 300, 20, 10);
//m<1
lineBres(20, 10, 300, 40);
lineBres(300, 40, 20, 10);
lineBres(20, 40, 300, 10);
lineBres(300, 10, 20, 40);
//m>1
lineBres(20, 10, 300, 600);
lineBres(300, 600, 20, 10);
lineBres(20, 600, 300, 10);
lineBres(300, 10, 20, 600);
}