模块1 扫描转换算法
一 实验目的
二 实验理论分析
DDA法:
中点画线法:
Bresenham法:
三 实验内容
1:用DDA算法绘制任意斜率的直线
实验结果如下图所示:
![]() |
第一步:输入起点的坐标和终点的坐标(【100,100】为起点,【0,0】为终点)
![]() |
第二步:程序自动连接上述两点
2:用中点画线和Bresenham画线算法绘制部分斜率的直线
2.1-Bresenham画线算法实验结果如下图所示:
第一行的操作分别为:水平从左向右画线、从左下向右上画线、从左上向右下画线(不超过45度);
![]() |
第二行的操作分别为:从左上向右下画线(超过45度)、从右上向左下画线、从右下向左上画线;
2.2-中点画线算法实验结果如下图所示:
第一行的操作分别为:水平从左向右画线、从左下向右上画线、从左上向右下画线(不超过45度);
![]() |
第二行的操作分别为:从左上向右下画线(超过45度)、从右上向左下画线、从右下向左上画线;
3:用中点画线和Bresenham画线算法绘制任意斜率的直线
3.1-Bresenham画线算法实验结果如下图所示:
第一行的操作分别为:水平方向画线(左->右,右->左)、从左上向右下画线(k的绝对值大于1,k的绝对值小于1)、从左下向右上画线(k的绝对值大于1,k的绝对值小于1);
![]() |
第二行的操作分别为:从右上向左下画线(k的绝对值大于1,k的绝对值小于1)、从右下向左上画线(k的绝对值大于1,k的绝对值小于1)、竖直方向画线(上->下,下->上);
3.2-中点画线算法实验结果如下图所示:
![]() |
从任一点出发,即当前点为起点,在四周画出其他的任意斜率的直线。最终结果为如下的辐射状的图形,即可证明该算法可以画出任意斜率的直线。
四 程序说明
Project中程序的调用:
将当前cpp文件的属性——常规——从生成中排除中选择否,其他文件选择是,即可运行当前的cpp文件
1题 |
// // 程序名称:DDA // 功 能:用DDA算法绘制任意斜率的曲线 // 编译环境:VS2019,EasyX_20220116 // 最后修改:2022-3-3 #include #include #include #include using namespace std; void DDA_Line(int x0, int y0, int x1, int y1, int color){ int dx = x1 - x0, dy = y1 - y0, step, k; float x = x0, y = y0, xIncre, yIncre; //斜率绝对值大于1的时候,以 y 的变化为基准 if (abs(dx) > abs(dy)) { step = abs(dx); } else { step = abs(dy); } //x和y的增量计算 xIncre = (float)dx / (float)step; yIncre = (float)dy / (float)step; for (k = 0; k < step; k++) { putpixel(int(x + 0.5f), (int)(y + 0.5f), color); x += xIncre; y += yIncre; } } int main(){ int x1, y1, x2, y2; cout << "please input the start point:" << endl; cin >> x1 >> y1; cout << "please input the end point:" << endl; cin >> x2 >> y2;
initgraph(640, 480); DDA_Line(x1, y1, x2, y2, WHITE); _getch(); closegraph(); return 0; } |
2题:中点画线 |
// // 程序名称:中点画线 // 功 能:用中点画线算法绘制部分斜率的曲线 // 编译环境:VS2019,EasyX_20220116 // 最后修改:2022-3-3 #include #include #include #include using namespace std; void MidPointLine(int x0, int y0, int x1, int y1, int color) { int dx, dy, increE, increNE, d, x, y; dx = x1 - x0; dy = y1 - y0; d = dx - 2 * dy; increE = -2 * dy; increNE = 2 * (dx - dy); x = x0; y = y0; putpixel(x, y, color); while (x < x1) { if (d > 0) { d += increE; x++; } else { d += increNE; y++; x++; } putpixel(x, y, color); } } int main(){ initgraph(640, 480); ExMessage m; int x0, y0, x1, y1; while (true) { m = getmessage(EX_MOUSE | EX_KEY); switch (m.message) { case WM_LBUTTONDOWN: x0 = m.x; y0 = m.y; setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_RBUTTONDOWN: x1 = m.x; y1 = m.y; MidPointLine(x0, y0, x1, y1, WHITE); setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_KEYDOWN: if (m.vkcode == VK_ESCAPE) return 0; // 按 ESC 键退出程序 } } closegraph(); return 0; } |
2题:Bresenham画线 |
// // 程序名称:bresenham画线 // 功 能:用bresenham画线算法绘制部分斜率的曲线 // 编译环境:VS2019,EasyX_20220116 // 最后修改:2022-3-3 #include #include #include #include using namespace std; void bresenham(int x0, int y0, int x1, int y1, int color) { int x, y, dx, dy, i, e; dx = x1 - x0; dy = y1 - y0; e = -dx; x = x0; y = y0; for (i = 0; i <= dx; i++) { putpixel(x, y, color); x++; e += 2 * dy; if (e >= 0) { y++; e -= 2 * dx; } } } int main() { initgraph(640, 480); ExMessage m; int x0, y0, x1, y1; while (true) { m = getmessage(EX_MOUSE | EX_KEY); switch (m.message) { case WM_LBUTTONDOWN: x0 = m.x; y0 = m.y; setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_RBUTTONDOWN: x1 = m.x; y1 = m.y; bresenham(x0, y0, x1, y1, WHITE); setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_KEYDOWN: if (m.vkcode == VK_ESCAPE) return 0; // 按 ESC 键退出程序 } } closegraph(); return 0; } |
3题:中点画线 |
// // 程序名称:中点画线:加强版 // 功 能:用中点画线算法绘制任意斜率的曲线 // 编译环境:VS2019,EasyX_20220116 // 最后修改:2022-3-3 #include #include #include #include using namespace std; void MidPointLine(int x0, int y0, int x1, int y1, int color) { int a, b, d1, d2, d, x, y; float m; if (x1 < x0) { d = x0; x0 = x1; x1 = d; d = y0; y0 = y1; y1 = d; } a = y0 - y1; //y差值 b = x1 - x0; //x差值 if (b == 0) { m = -1 * a * 100; } else { m = (float) a / (x0 - x1); } x = x0; y = y0; putpixel(x, y, color); //斜率在0~1 if (m >= 0 && m <= 1){ d = 2 * a + b; d1 = 2 * a; d2 = 2 * (a + b); while (x < x1) { if (d <= 0) { x++; y++; d += d2; } else { x++; d += d1; } putpixel(x, y, color); } } //斜率在-1~0 else if (m <= 0 && m >= -1) { d = 2 * a - b; d1 = 2 * a - 2 * b; d2 = 2 * a; while (x < x1) { if (d > 0) { x++; y--; d += d1; } else { x++; d += d2; } putpixel(x, y, color); } } //斜率在1~∞ else if (m > 1) { d = a + 2 * b; d1 = 2 * (a + b), d2 = 2 * b; while (y < y1) { if (d > 0) { x++; y++; d += d1; } else { y++; d += d2; } putpixel(x, y, color); } } //斜率在∞~-1 else { d = a - 2 * b; d1 = -2 * b, d2 = 2 * (a - b); while (y > y1) { if (d <= 0) { x++; y--; d += d2; } else { y--; d += d1; } putpixel(x, y, color); } } } int main() { initgraph(640, 480); ExMessage m; int x0, y0, x1, y1; while (true) { m = getmessage(EX_MOUSE | EX_KEY); switch (m.message) { case WM_LBUTTONDOWN: x0 = m.x; y0 = m.y; setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_RBUTTONDOWN: x1 = m.x; y1 = m.y; MidPointLine(x0, y0, x1, y1, WHITE); setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_KEYDOWN: if (m.vkcode == VK_ESCAPE) return 0; // 按 ESC 键退出程序 } } closegraph(); return 0; } |
3题:Bresenham画线 |
// // 程序名称:bresenham画线:加强版 // 功 能:用bresenham画线算法绘制任意斜率的曲线 // 编译环境:VS2019,EasyX_20220116 // 最后修改:2022-3-3 #include #include #include #include using namespace std; void bresenham(int x0, int y0, int x1, int y1, int color) { int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1; int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1; int erro = (dx > dy ? dx : -dy) / 2; while (putpixel(x0, y0, color), x0 != x1 || y0 != y1) { int e2 = erro; if (e2 > -dx) { erro -= dy; x0 += sx; } if (e2 < dy) { erro += dx; y0 += sy; } } } int main() { initgraph(640, 480); ExMessage m; int x0, y0, x1, y1; while (true) { m = getmessage(EX_MOUSE | EX_KEY); switch (m.message) { case WM_LBUTTONDOWN: x0 = m.x; y0 = m.y; setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_RBUTTONDOWN: x1 = m.x; y1 = m.y; bresenham(x0, y0, x1, y1, WHITE); setfillcolor(GREEN); fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3); case WM_KEYDOWN: if (m.vkcode == VK_ESCAPE) return 0; // 按 ESC 键退出程序 } } closegraph(); return 0; } |