翻译
布兰森汉姆绘制线算法
1 第一次尝试
第一课的目标是渲染金属丝网。要做到这一点,我们应该学习如何绘制线段。我们可以简单地读懂Bresenham的行算法,但是让我们自己写代码。在(x0, y0)点和(x1, y1)点之间绘制线段的最简单代码是什么样子的?
显然,是这样的:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
for (float t=0.; t<1.; t+=.01) {
int x = x0 + (x1-x0)*t;
int y = y0 + (y1-y0)*t;
image.set(x, y, color);
}
}

可用代码片段here
2 第二次尝试
这段代码的问题(除了效率低下)是选择常数,我取它等于.01。
如果取它为.1,线段就会像这样

我们可以很容易地找到必要的步骤:它就是要绘制的像素数。
最简单的(但错误的)代码看起来像以下:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
for (int x=x0; x<=x1; x++) {
float t = (x-x0)/(float)(x1-x0);
int y = y0*(1.-t) + y1*t;
image.set(x, y, color);
}
}
注意!
在我的学生的代码中,第一个错误的来源是整数除法,比如’ (x-x0)/(x1-x0) '。
然后,如果我们尝试用这段代码绘制以下线条:
line(13, 20, 80, 40, image, white);
line(20, 13, 40, 80, image, red);
line(80, 40, 13, 20, image, red);

原来一条线是好的,第二条是有孔的,第三条线根本就没有。
注意,第一行和第三行(在代码中)以不同的颜色和不同的方向绘制了同一条线(源点和目标点翻转了)。
我们已经看过白色的了,画得很好。
我希望把白线的颜色改成红色,但是我做不到。
这是对对称性的测试:绘制线段的结果不应该依赖于点的顺序:(a,b)线段应该与(b,a)线段完全相同。
3 第三次尝试
我们通过交换点来修复缺失的红线,使x0总是小于x1。
在其中一个线段上有洞,这是由于它的高度大于宽度。
我的学生经常提出以下解决办法:

本文详细介绍了优化Bresenham线算法的过程,从初步实现到逐步消除性能瓶颈,包括代码优化和浮点运算的替代方案。通过分析和测试,展示了如何减少不必要的像素设置和提高渲染效率,最终实现线框渲染的高效实现。
最低0.47元/天 解锁文章
4645





