算法原理
对于直线y=kx判断,每当x加一时,y是否加一。y值得变换主要根据其误差项e,如图所示
图中e即误差项,当时,取
,当
时,取
。
其中e即为斜率k,即根据
令,则
当时
;
当时
;
即针对这两种情况,有两种不同的处理方法,根据下图可看出
当时,此时对于
的取值需根据其误差项2e判断
令,同样根据
的值判断取点;
同理对于,根据图中发现
令
伪码流程
1、将左端点存入
2、计算出斜率k
3、画出第一个点并计算出
(注意k为斜率k的绝对值)
4、
若,则下一个绘制的点坐标为
,
若,则下一个绘制的点坐标为
,
5、重复步骤4
代码展示
#include<iostream>
#include<graphics.h>
#include <conio.h>
using namespace std;
#define X 500
#define Y 500
void Bresenham(int x0, int y0, int x1, int y1) {
int dx, dy;
dx = x1 - x0;
dy = y1 - y0;
double k;
k = 1.0 * dy / dx;
double t0, t1;
if (abs(k) <= 1) {
if (x0 > x1) {
int t = x0;
int t1 = y0;
x0 = x1;
y0 = y1;
x1 = t;
y1 = t1;
}
for (int x = x0, y = y0; x < x1; x++) {
if (x == x0) {
putpixel(X + x, Y - y, WHITE);
t0 = 2 * abs(k) - 1;
continue;
}
if (t0 >= 0) {
if (k > 0) {
y = y + 1;
}
else {
y = y - 1;
}
}
putpixel(X + x, Y - y, WHITE);
t1 = t0;
if (t1 >= 0) {
t0 = t1 + 2 * abs(k) - 2;
}
else {
t0 = t1 + 2 * abs(k);
}
}
}
else {
if (y0 > y1) {
int t = x0;
int t1 = y0;
x0 = x1;
y0 = y1;
x1 = t;
y1 = t1;
}
for (int x = x0, y = y0; y < y1; y++) {
if (y == y0) {
putpixel(X + x, Y - y, WHITE);
t0 = 2 - abs(k);
continue;
}
if (t0 >= 0) {
if (k > 0) {
x = x + 1;
}
else {
x = x - 1;
}
}
putpixel(X + x, Y - y, WHITE);
t1 = t0;
if (t1 >= 0) {
t0 = t1 + 2 - 2 * abs(k);
}
else {
t0 = t1 + 2;
}
}
}
}
int main() {
// 生成画布
initgraph(1200, 800);
// 生成坐标系
for (int x = 300; x < 700; x++) {
putpixel(x, Y, RED);
}
for (int y = 300; y < 700; y++) {
putpixel(X, y, RED);
}
putpixel(X, Y, WHITE);
// 读入数据
int x0, y0, x1, y1;
cout << "请输入起点坐标:";
cin >> x0 >> y0;
cout << "请输入终点坐标:";
cin >> x1 >> y1;
// Bresenham算法绘制直线
Bresenham(x0, y0, x1, y1);
cout << "按任意键退出。" << endl;
// 按任意键退出
_getch();
// 关闭画布
closegraph();
return 0;
}