作业要求:
1. 请采用中点画线法和 Bresenham 法绘制直线(共100 分)。
要求: (1) 给出每种算法的文字描述(共 50 分,每种算法各 25 分)。 (2) 编写函数,在给定起点和终点的情况下,计算出直线上 其它的点,并将这些点存储在数组中(共 50 分,每个函数各 25 分)。
中点画线法
一、算法的文字描述
首先需要根据直线段的斜率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;
}
}
}
}