作业要求:
1. 请采用中点画线法和 Bresenham 法绘制直线(共100 分)。
要求:
(1) 给出每种算法的文字描述(共 50 分,每种算法各 25 分)。
(2) 编写函数,在给定起点和终点的情况下,计算出直线上 其它的点,并将这些点存储在数组中
中点画线法
一、算法的文字描述
首先需要根据直线段的斜率k,除了斜率不存在的情况(该情况直线可以直接画出)将直线划分为k>1、0<=k<=1、-1<=k<0、k<-1 四种情况,当0<=k<=1、-1<=k<0时,x方向为主位移方向;k>1、k<-1时,y方向为主位移方向。
以下做分类说明:
1.在0<=k<=1时的中点画线算法:
2.在-1<=k<0时的中点画线算法:
3.在k>1时的中点画线算法:
|
4.在k<-1时的中点画线算法:
|
二 、编写函数,在给定起点和终点的情况下,计算出直线上其它的点,并将这些点存储在数组中
void MidLine(int x1, int y1, int x2, int y2)
{
linepoint linepoints[N]; int i{0};double k{ 0 };
int dx, dy, d, Deta1, Deta2, x, y;
if (x1 != x2) k = (1.0 * y2 - y1) / (x2 - x1);
if ((x1 > x2 && abs(k) <= 1)||(y1 > y2 && abs(k) > 1))
{
x = x2; x2 = x1; x1 = x; y = y2; y2 = y1; y1 = y;
}
//初始化
x = x1; y = y1;dx = x2 - x1; dy = y2 - y1;
if (k >= 0 && k <= 1)
{
Deta1 = -2 * dy ; Deta2 = 2 * dx - 2 * dy; d = dx - 2 * dy;
while (x < x2)
{
linepoints[i].x = x; linepoints[i++].y = y;
x++;
if (d < 0)
{
y++;d += Deta2;
}
else
d += Deta1;
}
}
else if (k <= 0 && k >= -1)
{
Deta1 = -2 * dy; Deta2 = -2 * dx - 2 * dy; d = -dx - 2 * dy;
while (x < x2)
{
linepoints[i].x = x; linepoints[i++].y = y;
x++;
if (d >= 0)
{
y--;d += Deta2;
}
else
d += Deta1;
}
}
else if (k > 1)
{
Deta1 = 2 * dx; Deta2 = 2 * dx - 2 * dy; d = 2 * dx - dy;
while (y < y2)
{
linepoints[i].x = x; linepoints[i++].y = y;
y++;
if (d >= 0)
{
x++;d += Deta2;
}
else
d += Deta1;
}
}
else
{
Deta1 = 2 * dx; Deta2 = 2 * dx + 2 * dy; d = 2 * dx + dy;
while (y < y2)
{
linepoints[i].x = x; linepoints[i++].y = y;
y++;
if (d <0)
{
x--;d += Deta2;
}
else
d += Deta1;
}
}
}
Bresenham 法
一、算法的文字描述
同样地,需要分为k>1、0<=k<=1、-1<=k<0、k<-1 四种情况,当0<=k<=1、-1<=k<0时,x方向为主位移方向;k>1、k<-1时,y方向为主位移方向。e的值用2e∆x的形式。
以下做分类说明:
1.在0<=k<=1时的中点画线算法:
2.在-1<=k<0时的中点画线算法:
3.在k>1时的中点画线算法:
|
4.在k<-1时的中点画线算法:
可看出计算误差e时,|k|>1和|k|<1的计算公式仅是dx和dy交换的结果。且|k|>1的两种情况和|k|<1的两种情况的误差及误差增量计算实际上是分别相同的。|k|<1时,e初值为2|dy|-|dx|,e<0时增量为2|dy|,反之是2|dy|-2|dx|。|k|>1时做相应的dx和dy交换即可。 |
二、编写函数,在给定起点和终点的情况下,计算出直线上其它的点,并将这些点存储在数组
void BresenhamLine(int x0, int y0, int x1, int y1)
{
linepoint linepoints[N]; int i{0}; double k{0};int dx, dy, e{0},x, y;
if(x0!=x1) k = (1.0 * y1 - y0) / (x1 - x0);
if (x0 > x1&&abs(k)>0&&abs(k)<=1)
{
x = x1; x1 = x0; x0 = x;y = y1; y1 = y0; y0 = y;
}
else if (y0 > y1 && abs(k) > 1)
{
x = x1; x1 = x0; x0 = x;y = y1; y1 = y0; y0 = y;
}
x = x0; y = y0;dx = abs(x1 - x0); dy = abs(y1 - y0);
if (abs(k) <= 1)
{
while(x<x1)
{
e = 2 * dy - dx;
linepoints[i].x = x; linepoints[i++].y = y;
x++;
if (e < 0)
e += 2 * dy;
else
{
if (y1 > y0) y++;
else y--;
e += 2 * dy - 2 * dx;
}
}
}
else
{
while(y<y1)
{
e = 2 * dx - dy;
linepoints[i].x = x; linepoints[i++].y = y;
y++;
if (e < 0)
e += 2 * dx;
else
{
if (x1 > x0) x++;
else x--;
e += 2 * dx - 2 * dy;
}
}
}
}