可能有图片或下载的链接不对,请到原始地址查看.http://dgame.yeah.net
========================================================
普通的Breshenham算法画线很快,但并不是很精细.通常的整数画线因为只能在整数坐标上绘图,所以产生难看的锯
齿.我在Michael Abrash的一本书力看到一个很好的反走样直线画法,并决定用非整数坐标改进他.
![]() |
一个wu直线不但仅是看上去比一个普通直线好,他也产生更好的动画.一个普通的直线从一个位置简单的跳到下一个 位置.然而,一条wu直线很悠闲的漂到下一个位置. |
他是如何工作的?
让我们想一下一个反走样直线究竟意味这什么.一条恰当的直线看上去应该是什么样的?直线有多粗?尾端应该是怎
么样的?直线是个一维物体,无限长.他没有什么粗细.线段的尾端看上去什么都不象,他就是尾端而已.这样一个直
线不能被画到一个基于像素的显示设备上.
在电脑图像中,通常假定线段为一个像素粗.这意味这他能够被画下来.这也意味着他足够细使得不必考虑他的末
端应该是什么样子,因为他比一个像素还小,不能够画.
在我们设计一个新的wu直线的时候我们必须定制类似的假定.因为这个新的算法能够处理非整数坐标的端点,对于一
个小于一像素长的线能做什么呢?
假定
.假定像素在他们坐标的中央
.直线是个像素粗
.直线的末端的形状不重要
他能够更好,假如:
.两个平行线段,端点相连接,不能分辨出其中一个,一个长线段
.直线的亮度/透明的能够被定义
最终的算法是怎样的?
最终的算法相当容易实现,但是在实际应用中显得太慢.但也不是真正的必要,因为他的效果和另一个更快速的方法
几乎相同.不管怎样,我将阐明一些基本的东西.
![]() |
想像一下,您能够能够放大我们在上面画线的屏幕的像素.理想的画线算法将计算每条线覆盖的精确的区域,从而增 加那些像素的亮度. 这样一个算法很容易写,在一个更高的分辨率重画屏幕的相关部分,然后把线画到上面,计算出覆盖的像素或 calculating it presicely. |
![]() |
然而这需要一些精确度.我们来看下一种方法.
一个更明智的算法
![]()
|
这个算法跨骑着直线绘制一对像素.一个主循环将沿着直线的长度画一对像素,端点的像素对将被分别计算. 像素对: 再想像一次,屏幕的一个特写.画一条几乎水平的线. 这个几乎水平的线穿过垂直的像素列.每次跨过像素,x坐标是整数,但是y坐标是非整数. 看的更近些,一个单个的跨越点: |
绘制端点
最后的事情就是画端点.这不好处理,我仍然没有完全正确的处理他们.这里是我现在用的一种方法.他不很理想,但
是很近似.您将注意到在直线从几乎垂直变得几乎水平的时候他有小心的失灵,反过程也是.您将在直线缓慢的移
动过45度的时候注意到这点.
真正近距离的看一下端点:
能够看到直线的一个端点,用红色的点来表示.蓝色的点表示像素的中央点.您能够看到,顶点不在像素的中央点上.
计算直线端点的两个像素的正确亮度:
.把直线延长(向后或向前)到最近的整数x坐标(p).向计算直线上普通的像素对的亮度相同计算这个像素对.然后,因
为直线只是覆盖这个像素的很小一部分(i),直线将降低他的亮度.所以亮度应该乘上i.因此,当整条直线向右移动,i
将变小,使得这个像素对平滑的变暗.
特别的情况
一个长度小于一像素的直线将是怎样的呢?因为他的长度太小以至不能精确表现,所以您能够随便按他应该的模样画
.这是我自己的实现方法,我把线拉伸到一个像素常,然后降低他们的亮度.所以一个很短的直线看上去很暗,当他
变长,他就会变亮,当他是个像素常,他在所在点上将被正常的画出.
最后,一些伪代码
| wu直线的定点数计算需要的一些函数: function trunc(x) return integer part of x end of function function frac(x) return fractional part of x end of function function invfrac(x) return 1 - (fractional part of x) end of function |
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!










