我们使用的环境是MFC单文档项目,采用Visual Studio 2013 版本。
我们将平面划分成十个部分,从第一象限的x轴开始做逆时针旋转,每隔45度角为一部分,由此类推到第八部分。Y轴正向为第九部分,负向为第十部分。
数字微分法的算法思路,是用数值方法解微分方程,即通过对x和y各增加一个小增量,计算下一步的x、y值。因此各不同区域的△x和△y值各不相同。具体如下;
区域 | △x | △y |
1 | 1 | K |
2 | 1/k | 1 |
3 | -1 | K |
4 | -1/k | 1 |
5 | -1 | -k |
6 | -1/k | -1 |
7 | 1 | -k |
8 | 1/k | -1 |
9 | 0 | -1 |
10 | 0 | 1 |
设dx为终点坐标x值x1减去起点坐标x值x0的大小,同理于dy,K为直线斜率。
我们可以通过上表中给出的递增值画出不同区域中的直线。不同的区域通过计算直线斜率和始末点位置判断。程序编写时先行通过if判断语句划分区域,而后通过switch语句执行不同区域的画线程序。
OnDdaline()
{
*pDC = GetDC(); //获得设备指针
dx = (float)(x1 - x0);
dy = (float)(y1 - y0);
k = dy / dx;
Dx = abs(dx);
Dy = abs(dy);
x = x0;
y = y0;
state = 0; //状态标识
//状态分析
if (dx > 0)
{
if (dy < 0)
{
if (Dx >= Dy)
state = 1;
else
state = 2;
}
else
{
if (Dx >= Dy)
state = 8;
else
state = 7;
}
}
else if (dx < 0)
{
if (dy < 0)
{
if (Dx <= Dy)
state = 3;
else
state = 4;
}
else
{
if (Dx <= Dy)
state = 6;
else
state = 5;
}
}
else if (dy < 0)
state = 9;
else
state = 10;
switch (state)
{
case 1:
for (; x <= x1; x++)
{
pDC->SetPixel(x, int(y + 0.5), c);
y = y + k;
}
break;
case 2:
for (; y >= y1; y--)
{
pDC->SetPixel(int(x + 0.5), y, c);
x = x - 1 / k;
}
break;
case 3:
for (; y >= y1; y--)
{
pDC->SetPixel(int(x + 0.5), y, c);
x = x - 1 / k;
}
break;
case 4:
for (; x >= x1; x--)
{
pDC->SetPixel(x, int(y + 0.5), c);
y = y - k;
}
break;
case 5:
for (; x >= x1; x--)
{
pDC->SetPixel(x, int(y + 0.5), c);
y = y - k;
}
break;
case 6:
for (; y <= y1; y++)
{
pDC->SetPixel(int(x + 0.5), y, c);
x = x + 1 / k;
}
break;
case 7:
for (; y <= y1; y++)
{
pDC->SetPixel(int(x + 0.5), y, c);
x = x + 1 / k;
}
break;
case 8:
for (; x <= x1; x++)
{
pDC->SetPixel(x, int(y + 0.5), c);
y = y + k;
}
break;
case 9:
for (; y >= y1; y--)
{
pDC->SetPixel(x, y, c);
}
break;
case 10:
for (; y <= y1; y++)
{
pDC->SetPixel(x, y, c);
}
break;
default:
break;
}
ReleaseDC(pDC); //释放设备指针
}