图形算法:直线算法

本文详细介绍了直线算法,包括直线方程、DDA算法和重点讲解的Bresenham算法,涵盖斜率大于1、小于1、大于-1小于0及小于-1的情况。Bresenham算法通过整数增量计算,实现高效精确的光栅线生成,适用于不同斜率的线段绘制。
摘要由CSDN通过智能技术生成

图形算法:直线算法

标签(空格分隔): 算法

版本:3
作者:陈小默
声明:禁止商用,禁止转载

发布于:作业部落CSDN博客


场景中的直线由其两端点的坐标位置来定义。要在光栅监视器中显示一条线段,图形系统必须先将两端点投影到整数屏幕坐标,并确定离两端点间的直线路径最近的像素位置。接下来才是将颜色填充到相应的像素坐标。1

前言


文章最后的演示代码使用的是C++语言,函数库使用的是以GLUT为基础的自定义封装库。本章内容将介绍生成直线的直线方程算法DDA算法以及重要的Bresenham算法

一、算法导论

以下仅仅展示算法的计算过程,具体实施请参考示例程序部分。


1.1直线方程算法

对于绘制直线来说,使用直线方程无疑是一种最直接的算法。在二维笛卡尔坐标系中,直线方程为:

y=m*x+b \tag{1.1}\label{1.1}

其中m代表直线的斜率,b为直线的截距,对于任意两个端点 (x0,y0) (x1,y1)
m=y1y0x1x0(1.2)

b=y0mx0(1.3)

由于屏幕上的点在其坐标系中以整数表示,当斜率 1>|m| 时,我们可以以 x 轴增量 δx 计算相应的y轴增量 δy
\delta y=m*\delta x\tag{1.4}\label{1.4}

同样,对于斜率 |m|>1 的线段,我们需要通过以 y 轴增量 δy 计算相应的 x 轴增量 δx

\delta x=\frac{\delta y}{m} \tag{1.5}\label{1.5}

通过使用直线方程绘制的点,其优点是算法简单且精确,但是其在绘制每一个点的过程中都需要计算一次乘法和加法,显而易见,由于乘法的存在,导致运算时间大幅度增加。接下来介绍的DDA算法将弥补直线方程的乘法缺陷。

1.2 DDA算法

从上可知,在绘制大量点的过程中,我们要尽可能的减少每一个点的计算时间。在计算机中加法运算是最简单的运算之一了。我们可以利用直线的微分特性将每一步的乘法运算替换为加法运算。数字微分分析法(Digital Differential Analyzer,DDA)是一种线段扫描转换算法,基于式 (1.4) (1.5) 来计算 δx δy

对于斜率 |m|1 的线段来说,我们仍以单位 x (δx=1) 间隔(考虑到屏幕设备坐标为连续整数)取样,并逐个计算每一个 y 值。

y_{k+1}=y_k+m \tag{1.6}\label{1.6}

于是,我们便将乘法运算合理的转换为了加法运算。但是需要注意的是,在屏幕设备中的坐标均是整数,所以我们在绘制时的y需要取整。
对于具有大于1的正斜率线段,则需要交换 x y 的位置。也就是以单位 y 间隔 (δy=1) 取样,顺序计算每一个 x 的值

x_{k+1}=x_k+\frac{1}{m} \tag{1.7}\label{1.7}

此时,每一个计算出的 x 要沿着 y 扫描线舍入到最近的像素位置。

该算法只需要计算出一个 step 值( m 或者 1m ),然后就可以沿着路径的方向计算出下一位像素。然而,该算法的缺点显而易见,在数学上,该算法能够保证计算结果准确无误,但是,由于计算机中的数据类型具有精度限制,这将会导致大量数据处理的误差积累。并且,其虽然消除了直线方程中的乘法运算,但是对于浮点数的运算和取整仍然十分耗时。

1.3 Bresenham算法


接下来我们介绍由布莱森汉姆(Bresenham)提出的精确且高效的光栅线生成算法,该算法仅仅使用整数增量计算,除此之外,该算法还能应用于圆或者其他曲线。

我们将分别介绍四种斜率( m>1 0<m<1 1<m<0 m<1 )的计算过程(以下示例均为从左至右画线)。

1.3.1 斜率大于1

图1.3.1_1

首先,在斜率大于1的情况下,沿路径像素以单位 y 间隔取样。假设线段以 (x0,y0) 开始对于其路径上已绘制的 (xk,yk) 点我们需要判定下一个点的绘制位置是 (xk+1,yk+1) 还是 (xk,yk+1)

在取样位置 yk+1 我们使用 dleft dright 来标识两个像素位置( xk xk+1 )与数学位置的水平偏移量。根据式 (1.1) 可得在像素列 yk+1 处的 x 坐标计算值为

x=\frac{(y_{k+1}-b)}{m}=\frac{(y_k+1-b)}{m} \tag{1.8}\label{1.8}

所以

d_{left}=x-x_k=\frac{y_k+1-b}{m}-x_k \tag{1.9}\label{1.9}

d_{right}=x_{k+1}-x=x_k+1-\frac{y_k+1-b}{m} \tag{1.10}\label{1.10}

为了确定两个像素中哪一个更接近真实路径,需要计算两个像素偏移的差值。

d_{left}-d_{right}=2\frac{y_k+1-b}{m}-2x_k-1 \tag{1.11}\label{1.11}

设线段终点位置为 (x1,y1) ,可得

m=\frac{\Delta y}{\Delta x}=\frac{y_1-y_0}{x_1-x_0} \tag{1.12}\label{1.12}

设决策参数 pk=Δy(dleftdright)

p_k=2\Delta xy_k-2\Delta yx_k+C \tag{1.13}\label{1.13}

其中

C=2\Delta x(1-b)-\Delta y \tag{1.14}\label{1.14}

在第 k+1 步,决策参数可以由式 (1.13) 计算得出

p_{k+1}=2\Delta x(y_k+1)-2\Delta yx_{k+1}+C \tag{1.15}\label{1.15}

将上述等式减去式 (1.13) 可得决策值的增量 δpk+1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值