Bresenham算法

算法原理

对于直线y=kx判断,每当x加一时,y是否加一。y值得变换主要根据其误差项e,如图所示

图中e即误差项,当e\geq 0.5时,取y^{(1)},当e\leqslant 0.5时,取y^{(2)}

其中e即为斜率k,即根据

e-0.5=k-0.5=\frac{2k-1}{2}

t_0 = 2k-1,则

t_0\geqslant 0y_1 = y_0 + 1

t_0<0y_1 = y_0

即针对这两种情况,有两种不同的处理方法,根据下图可看出

t_0<0时,此时对于y_2的取值需根据其误差项2e判断

2e-0.5=2k-0.5=\frac{4k-1}{2}

t_1=4k-1=t0+2k,同样根据t_1的值判断取点;

同理对于t_2,根据图中发现t_1\geqslant 0

e_3=3k-1-0.5=\frac{6k-3}{2}

t_2=6k-3=t1+2k-2

伪码流程

1、将左端点存入(x_0,y_0)

2、计算出斜率k

3、画出第一个点(x_0,y_0)并计算出t_0=2k-1(注意k为斜率k的绝对值)

4、

t_0\geq 0,则下一个绘制的点坐标为(x_k,y_k) = (x_{k-1}+1,y_{k-1}+1)t_0=t_0+2k-2

t_0<0,则下一个绘制的点坐标为(x_k,y_k)=(x_{k-1}+1,y_{k-1})t_0=t_0+2k

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值