直线和圆弧的生成算法
03-第三章 直线和圆弧的生成算法(上)网络学堂_547501374
Bresenham 直线算法
(3) Q d1=y-yk, y=m(xk+1)+b= m(xk+1)+b ∴d1= m(xk+1)+b-yk, d2=1- d1 d1-d2=d1-1+d1 =2d1-1 = 2m(xk+1)+2b-2yk-1 =2m xk -2yk+ 2m+2b-1 =2m xk -2yk+c (令c=2m+2b-1 为常数) =2(xk∆y-yk∆x)/∆x+c
d2=1-m
d1=m
y
y0
x0
x1
Bresenham 直线算法
(5)续 Q pk= ∆x(d1-d2 ) ∴ p0= ∆x(d1-d2 ) 又 Q d1=m, d2 =1-m ∴ p0= ∆x(d1-d2 ) = ∆x(m-1+m) = ∆x(2m-1) = ∆x(2∆y/∆x -1) = 2∆y-∆x
也有利于硬件电路的实现(集成电路)
Bresenham 直线算法
举例: 从(20, 10)到(30, 18)画一条直线 解: Q ∆x=30-20=10, ∆y=18-10=8 0<∆y<∆x ⇒ 0<m<1 ∴ p0=2∆y-∆x=6 2∆y=16, 2∆y-2∆x=- 4 x0=20, y0=10,
Bresenham 直线算法
(6) 整理 初始条件 x0=xs, y0=ys, p0= 2∆y-∆x 如果 pk<0 则 xk+1 =xk+1, yk+1=yk, pk+1=2 ∆y+ pk 否则 xk+1 =xk+1, yk+1=yk+1, pk+1=2 (∆y- ∆x) + pk
绘弧的算法
绘弧的算法绘弧是计算机图形学中的常见操作,用于绘制曲线或弧线形状。
在计算机图形学中,有多种算法可以实现绘制弧线的功能,本文将介绍其中几种常见的算法。
一、中点画圆法中点画圆法是一种常见的绘制圆弧的算法。
该算法通过计算圆弧上每个点的坐标来实现绘制。
具体步骤如下:1. 计算圆弧的起点和终点的坐标,以及圆心的坐标。
2. 计算圆弧的半径。
3. 初始化绘制点的坐标。
4. 根据圆弧的起点和终点坐标,确定绘制的起始角度和终止角度。
5. 循环遍历绘制点,通过计算每个点对应的角度和半径,计算出点的坐标。
6. 绘制圆弧。
二、贝塞尔曲线贝塞尔曲线是一种常用的曲线绘制算法,可以绘制平滑的曲线。
贝塞尔曲线可以通过控制点来定义曲线的形状。
常见的贝塞尔曲线有二次贝塞尔曲线和三次贝塞尔曲线。
1. 二次贝塞尔曲线二次贝塞尔曲线由起点、终点和一个控制点来定义。
通过调整控制点的位置,可以改变曲线的形状。
2. 三次贝塞尔曲线三次贝塞尔曲线由起点、终点和两个控制点来定义。
通过调整控制点的位置,可以改变曲线的形状。
贝塞尔曲线的绘制可以通过递归算法来实现。
具体步骤如下:1. 计算贝塞尔曲线上每个点的坐标。
2. 根据控制点的位置,计算出曲线上每个点的坐标。
3. 绘制贝塞尔曲线。
三、Bresenham算法Bresenham算法是一种直线绘制算法,也可以用于绘制圆弧。
该算法基于直线的斜率和误差修正来计算圆弧上的点。
具体步骤如下:1. 计算圆弧的起点和终点的坐标,以及圆心的坐标。
2. 初始化绘制点的坐标。
3. 计算圆弧的半径。
4. 根据圆弧的起点和终点坐标,确定绘制的起始角度和终止角度。
5. 根据起始角度和终止角度,计算圆弧上每个点的坐标。
6. 绘制圆弧。
以上是几种常见的绘制弧线的算法,每种算法都有其适用的场景和特点。
在实际应用中,可以根据具体需求选择合适的算法进行绘制。
通过合理选择和优化算法,可以高效地绘制出各种形状的弧线。
绘弧的算法在计算机图形学和图像处理中具有重要的应用价值,为实现各种美观的图形效果提供了基础支持。
计算机图形学第3章 基本图形生成算法
例题:有点P0(4,3);P1(6,5);P2(10,
6 );P3(12,4),用以上4点构造2次B样条曲线。
2.1.7 非均匀有理B样条
非均匀有理B样条NURBS(Non Uniform Rational BSpline);
3.2.2
Bresenham画圆法
该算法是最有效的算法之一。
不失一般性,假设圆心(xc,yc) ,圆上的点(x′,y′),则:
x' x xc
y ' y yc
圆心为原点,半径为R的位于第一象限1/8圆弧的画法,即(0, R)~( R , R )。
2 2
yi ), 思想:每一步都选择一个距离理想圆周最近的点P( xi , 使其误差项最小。
画其他曲线。
3.3
自由曲线的生成
正弦函数曲线
指数函数曲线
多项式函数曲线
自 由 曲 线
概率分布曲线及样条函数曲线
3.3.1 曲线的基本理论
基本概念
2.1.4
规则曲线:可用数学方程式表示出来的,如抛物 线等。
自由曲线:很难用一个数学方程式描述的,如高
速公路等。可通过曲线拟合(插值、逼近)的方法来
例题: 利用Bresenham算法生成P (0,0)到Q(6,5)的直 线所经过的像素点。要求先 列出计算式算出各点的坐标 值,然后在方格中标出各点。
(1,1)
3.1.5 双步画线法 原理
模式1:当右像素位于右下角时,中间像素位于底线 模式4:当右边像素位右上角时,中间像素位于中线 模式2和模式3:当右像素位于中线时,中间像素可能位于底线 上,也可能位于中线上,分别对应于模式2和模式3,需进一步 判断。 当0≤k≤1/2时,模式4不可能出现,当1/2≤k≤1时,模式1不 可能出现。
弧线长度的计算方法
弧线长度的计算方法
计算弧线长度的方法取决于弧线的形状和参数。
以下是一些常用的方法:
1. 直线段长度计算:直线段的长度可以通过两点之间的距离公式计算得到。
如果有多个直线段,则将每个直线段的长度相加得到总长度。
2. 圆弧长度计算:计算圆弧长度的常用方法是使用弧长公式。
弧长公式是根据圆的半径和弧度计算弧长的公式。
弧长公式为:弧长 = 半径 ×弧度。
其中,弧度以弧度制表示,可以通过将
角度转换为弧度来计算。
3. 椭圆弧长度计算:对于椭圆弧,没有简单的公式来计算其长度。
可以使用数值方法来估计椭圆弧的长度,例如通过将弧线分割成若干小段,并计算每个小段的长度,再将它们相加得到总长度。
4. 抛物线/双曲线长度计算:对于抛物线或双曲线弧线,也没
有统一的公式来计算其长度。
可以使用数值方法来估计弧线的长度,例如通过将弧线分割成若干小段,并计算每个小段的长度,再将它们相加得到总长度。
需要注意的是,以上方法只是估计弧线长度的一种方法,实际应用中可能存在误差。
如果需要更精确的长度值,可以考虑使用数值计算方法或采用其他数学工具进行计算。
计算机图形学-三种直线生成算法及圆的生成算法
计算机科学与技术学院2013-2014学年第一学期《计算机图形学》实验报告班级:110341C学号:110341328姓名:田野教师:惠康华成绩:实验(一):平面图形直线和圆的生成一、实验目的与要求1.在掌握直线和圆的理论基础上,分析和掌握DDA生成直线算法、中点生成直线算法、Bresenham生成直线算法、中点画圆算法、Bresenham圆生成算法。
2.熟悉VC6.0MFC环境,利用C语言编程实现直线和圆的生成。
3.比较直线生成三种算法的异同,明确其优点和不足。
同时了解圆的生成算法适用范围。
二、实验内容1.掌握VC6.0环境中类向导和消息映射函数的概念,并且为本次实验做好编程准备工作。
2. 用C语言进行编程实现上述算法,并且调试顺利通过。
3. 在MFC图形界面中显示不同算法下的图形,并且注意对临界值、特殊值的检验。
完成后保存相关图形。
三、算法分析➢DDA直线生成算法描述:1)给定一直线起始点(x0,y0)和终点(x1,y1)。
分别计算dx=x1-x0,dy=y1-y0。
2)计算直线的斜率k=dy/dx。
当|k|<1时转向3);当|k|<=1时,转向4);3)当x每次增加1时,y增加k。
即(xi,yi)→(xi+1,yi+k)。
直到xi增加到x1。
并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对y坐标要进行int(y+0.5)取整运算。
结束。
4)对y每次增加1时,x增加1/k,即(xi,yi)→(xi+1/k,yi+1)。
直到yi增加到y1. 并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对x坐标要进行int(x+0.5)取整运算。
结束。
➢中点生成算法描述:算法基本思想:取当前点(xp,yp),那么直线下一点的可能取值只能近的正右方点P1(xp+1,yp)或者P2(xp+1,yp+1)。
为了确定好下一点,引入了这两点中的中点M(xp+1,yp+0.5)。
这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。
计算机图形学课件第2讲:直线及圆生成算法
di 0 di 0
xi1 xi 1
22
中点画线算法
例:利用中点画线算法绘制一条直线:两端点分别为P0(0,0) 、P1(5,2)。
解:首先计算斜率k=0.4 ,因为斜率k小于1,故适用推导。
a=y0-y1=-2 , b=x1-x0=5 , d0=b=5 d1=2a=-4 , d2=2(a+b)=6
M
15
中点画线算法
令M为P1和P2的中点,易知M的坐标为 (xp+1,yp+0.5)。设Q是理想直线与垂直线x=xp+1的 交点。显然,若M在Q的下方,则P2离直线近,应 取为下一个像素;否则应P1 。
16
中点画线算法
问题:判断距离理想直线最近的下一个像素点
已知:线段两端点(x0,y0),(x1,y1) 直线方程:F(x,y)=ax+by+c=0
直线及圆生成算法
光栅图形学
Display processor
Frame buffer
Video Controller
Monitor
2
光栅图形学
0 1 2 ... 0 1 2 . . .
y
x 3
光栅图形学
4
二维图形的显示
是指完成图元的参数表示形式到点阵表示形式的 转换。通常也称扫描转换图元(Scan Conversion)
setPixel( x, y ); error = error + dy; if (error >= 0) { ++y; error = error - dx ; } }
33
斜率的问题
当斜率k>1, DDA, Bresenham算法:
34
圆弧生成算法
图3.9 对圆弧AB
要向下走一步得Pi+1,这是向圆内方 用正负法取点
向走去,取xi+1= xi, yi+1= yi-1
计算F(xi+1,yi+1)
分为两种情况:
F
xi
1
,
yi
1
F F
xi xi
, ,
yi yi
2xi 2 yi
1, 1,
Fxi , yi 0 Fxi , yi 0
➢当xi+1=xi+1,yi+1=yi时, F(xi+1,yi+1)=xi+12+yi2-R2 =xi2+yi2-R2+2xi+ =F(xi,yi)+2xi+1 ➢当xi+1=xi,yi+1=yi-1时, F(xi+,yi+1)=xi2+(yi-1)2-R2 =F(xi,yi)-2yi+1
di+1=(xi+1)2+y2i-R2+(xi+1)2+(yi-1)2-R2
=2x2i+4xi+2y2i-2yi-2R2+3
(3.17)
Di递推公式
di=2x2i+2y 2i-1-2yi-1-2R2+1
(3.16)
di+1=2x2i+4xi+2y2i-2yi-2R2+3 (3.17)
xi= xi-1+1
计算机图形学
1.1 正负法
基本原理:设圆的圆心在 (0,0),半径为R,则圆的方程 为
F(x,y)=x2+y2–R2=0
直线和圆弧的生成算法
第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。
当我们对直线进展光栅化时,需要在显示器有限个像素中,确定最优逼近该直线的一组像素,并且按扫描线顺序,对这些像素进展写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。
本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法〔DDA〕、中点画线法和Bresenham算法。
3.1.1逐点比拟法3.1.2数值微分(DDA)法设过端点P0(x0,y0)、P1(x1,y1)的直线段为L(P0,P1),如此直线段L的斜率L的起点P0的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个像素),用L的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round(y))作为当前点的坐标。
因为:y i+1= kx i+1+b= k1x i+b+k∆x= y i+k∆x所以,当 x =1; y i+1= y i+k。
也就是说,当x每递增1,y递增k(即直线斜率)。
根据这个原理,我们可以写出DDA〔Digital Differential Analyzer〕画线算法程序。
DDA画线算法程序:void DDALine(int x0,int y0,int x1,int y1,int color){ int x;float dx, dy, y, k;dx = x1-x0;dy=y1-y0;k=dy/dx,;y=y0;for (x=x0;x< x1;x++){ drawpixel (x, int(y+0.5), color);y=y+k;}}注意:我们这里用整型变量color表示像素的颜色和灰度。
举例:用DDA方法扫描转换连接两点P0〔0,0〕和P1〔5,2〕的直线段。
x int(y+0.5) y0 0 01 02 13 14 2图3 直线段的扫描转换注意:上述分析的算法仅适用于|k| ≤1的情形。
基本图形生成算法
Si (r 1, q)
(xi1, yi1)
y x dy dx
假设直线从 (x1, y1) 到 (x2 , y2 ) , 经变换后可表示为从 (0, 0) 到 (dx, dy) 其中 dx x2 x1 ,dy y2 y1 此时直线方程可简化为:
y dy x dx
(3 4)
将每一下标加1,即以i+1 代 i,则得:
di1 2xi dy 2 yidx 2dy dx
从 di1中减去 d i 得到:
di1 di 2dy(xi xi1) 2dx( yi yi1)
因为 xi xi1 1 ,重写上式得:
则令
dt 2m 所以
xinc dx 2m 1
yinc
dy
2m
1
即在x和y两个方向上,步长均小于1。若用硬件来实现对 称DDA法,则应用2套寄存器和加法器,将xinc和yinc分别加 到x和y的小数部分,哪个方向有整数溢出,就驱动该方向 走步。
数值微分法(DDA法)——特点
这种算法只需判断d的正负,其值的大小并不重要。 对于第一象限,因为分母 xM xA永远为正,所以只需 判断分子项的正负即可。我们得到偏差的判断公式 为:
FM yM xA yA xM
递推公式
用上式来计算偏差时,每次都要计算两次乘法,一 次减法,计算工作量还是很大的。如果我们设法用 前一点的偏差来推算走步方向以及走步以后的偏差, 则偏差计算就可以大大简化,也更适于计算机实现。 现在仍以第一象限为例,简述这种递推过程。
1
第五章 基本图形生成算法
图形生成的概念 直线段的扫描转换 圆的扫描转换 多边形的扫描转换与区域填充
图形学实验报告格式
图形学实验报告格式实验⼀直线、圆弧及曲线的⽣成算法⼀、实验⽬的1、⼏种直线⽣成算法的⽐较,特别掌握⽤Bresenham直线⽣成算法。
2、⼏种圆弧⽣成算法的⽐较,掌握Bresenham圆弧⽣成算法。
3、掌握⽤像素点法直接⽣成其它曲线的⽅法。
⼆、基本要求1、⽤不同的⽣成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜⾊表⽰区别。
2、⽤Bresenham⽣成算法在屏幕上绘制出圆弧的图形,⽤动画的⽅式表演图形的⽣成。
三、算法提⽰1、有关直线⽣成算法有:DDA(数值微分)直线算法、逐点⽐较法、直线Bresenham ⽣成算法。
直线Bresenham⽣成算法思想如下(第⼀象限,且斜率k<1的情况图2-1 a中的1a):1)画点(x1,y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-dx,i=1;2)求直线下⼀点位置x i+1=x i+1 如果P i>0,则y i+1=y i+1,否则y i+1=y i;3)画点(x i+1,y i+1);4)求下⼀个误差P i+1点,如果P i>0,则P i+1=P i+2dy-2dx,否则P i+1=P i+2dy;5)i=i+1,如果iBresenham⽣成算法的优点如下;1)不必计算直线的斜率,因此不做除法。
2)不⽤浮点数,只⽤整数。
3)只做整数加减运算和乘2运算,⽽乘2运算可以⽤移位操作实现。
Bresenham算法的速度很快,并适于⽤硬件实现。
对于图2-1 a中的2a,只需将x i+1=x i+1改为x i+1=x i-1。
对于图2-1 a中的1b,斜率k>1的情况,可交换变量x和y,y每次长1个单位。
对P i 进⾏判断,x i+1=x i或x i+1=x i+1。
2、有关圆弧⽣成算法有:逐点⽐较法、DDA(数值微分)直线算法、圆的Bresenham ⽣成算法。
圆的⽣成算法⼀般将圆划分为8等份,只需计算(900,450)的⼋分之⼀圆弧,其它⽤对称法求得(参见图2-1 b)。
直线 圆弧 偏移 算法
直线圆弧偏移算法
直线、圆弧和偏移算法是计算机图形学中常用的技术,用于处理图形的平移、旋转和变形。
这些算法在计算机辅助设计(CAD)、计算机游戏开发和动画制作等领域发挥着重要作用。
直线算法用于计算两点之间的直线路径,常见的算法包括数值微分法和Bresenham算法。
数值微分法通过对直线进行微分来计算直线上的点,而Bresenham算法则是一种更高效的算法,通过逐步逼近直线路径上的像素点来绘制直线。
圆弧算法用于绘制圆弧或曲线,常见的算法包括中点圆算法和Bezier曲线算法。
中点圆算法通过计算圆的对称性来绘制圆弧,而Bezier曲线算法则是一种基于控制点的曲线绘制方法,可以绘制出各种复杂的曲线。
偏移算法用于对图形进行平移或变形,常见的算法包括位移变换和仿射变换。
位移变换是一种简单的平移算法,通过将图形的每个顶点进行平移来实现整体平移;而仿射变换则是一种更复杂的变形算法,可以实现平移、旋转、缩放和错切等操作。
这些算法在计算机图形学中扮演着重要的角色,它们为我们提供了丰富多彩的图形效果和交互体验,同时也为计算机图形学的发展提供了坚实的基础。
通过不断的研究和创新,我们可以期待更多高效、精确的直线、圆弧和偏移算法的涌现,为计算机图形学的发展注入新的活力。
计算机图形学--第三讲 直线与圆生成算法
12直线生成算法圆弧绘制算法图元的概念33.1 图元的概念为其颜色值。
3.1 图元的概念3.1 图元的概念12直线生成算法圆弧绘制算法图元的概念33.2 直线生成算法曲线和各种复杂的图形均是离散成许多直线段来绘制,因而直线是二维图形生成技术的基础。
数学上的理想直线没有宽度,是由无数个点构成的集合。
对直线进行光栅化时,只能在显示器所给定的有限个像素组成的点阵中,选择能最好地逼近于该直线的一组像素,并对这些像素进行写操作。
这就是通常所说的用显示器绘制直线,即直线的扫描转换。
直线扫描转换的主要工作:快速找出像素点阵中最近的网格点3.2 直线生成算法画一条从近直线的像素序列,并填入色彩数据的过程。
这一过程也称为直线光栅化。
需要解决的问题►连续性►粗细、亮度要均匀►像素逼近待画直线►速度3.2 直线生成算法 问题1问题3.2 直线生成算法常用的直线生成算法有三种:►►►►►►3.2 直线生成算法基本思路:是用数值方法求解微分方程的一种方法,即根据长移动,由此产生连续的像素坐标3.2 直线生成算法设起点和终点坐标分别为Δx令即第3.2 直线生成算法于是有步的结果加上一个增量得到。
该算法在方向增量为3.2 直线生成算法3.2 直线生成算法下图中,用公式(表示,但显示时要用像素来表示,即采用舍入的办法得到最靠近空心圆点的像素,用这些像素(下图中的实心圆点)来表示直线。
3.2 直线生成算法void LineDDA(int{int} }3.2 直线生成算法►►想位置的偏移;►►整运算,运行效率低且取整运算不利于硬件实现基本思路:假定直线斜率P(x p,y的中点,---如果取---如果取---M与问题转换为如何判断构造判别式假设直线方程为:则由数学知识可知有下面的关系:F(F(F(所以,欲判断Q点下方,只需要把中点并检查它的符号。
构造判别式d=F(=a(当d<0取右上方当d≥0取右方P判别式的增量算法当增量为若增量为其它斜率的情况时再将算法设计:画线从d0可以用d0算法设计:例:用中点画线法12345void MidpointLine (int x { int a, b, d} /* mid PointLine */设直线的起点坐标为的情况来说明该算法。
基本图形的生成与计算-直线、圆、椭圆的生成
02
圆生成与计算
圆方程及性质
圆的标准方程
$(x-a)^2+(y-b)^2=r^2$,其中 $(a,b)$为圆心坐标,$r$为半径。
圆的性质
圆上任意一点到圆心的距离等于 半径;圆的任意两条直径互相平 分;垂直于弦的直径平分该弦。
圆绘制算法
确定圆心和半径
根据实际需求或已知条件确定圆 心和半径。
使用图形库
使用参数方程来表示图形的形状和位置 。参数方程可以是显式的或隐式的,可 以是二维的或三维的。参数方程表示法 可以方便地描述复杂的曲线和曲面。
VS
矩阵表示法
使用矩阵来表示图形的变换和操作。矩阵 表示法可以统一处理平移、旋转、缩放等 变换,使得计算更加简洁和高效。同时, 矩阵表示法也便于进行图形的复合变换和 复杂操作。
图形组合与拆分
图形组合
将多个图形组合成一个复杂的图形。组合方式可以是叠加、相交、相减等。组合后的图形可以具有更 加丰富的形状和特性。
图形拆分
将一个复杂的图形拆分成多个简单的图形。拆分方式可以是沿着边界、中心点、特定点等进行拆分。 拆分后的图形可以更容易地进行处理和分析。
图形参数化表示
参数方程表示法
将图形的大小按比例缩放。缩放因子可以是 任意正数,大于1表示放大,小于1表示缩小 。缩放可以沿着不同的轴进行,得到不同的 效果。
对称和对齐操作
对称操作
将图形关于某一直线或点进行对称。对称轴可以是任意直线,对称点可以是任意点。对称操作可以得到原图形 的镜像。
对齐操作
将图形与另一图形或坐标系进行对齐。对齐可以是水平对齐、垂直对齐或中心对齐等。对齐操作可以使得图形 在视觉上更加整齐和美观。
03
椭圆生成与计算
计算机图形学第3章
第3章 基本图形生成算法
3.1 生成直线的常用算法
均假定所画直线的斜率k∈[0,1]。
3.1.1 DDA画线算法
DDA(Digital Differential Analyzer)画线 算法也称数值微分法,是一种增量算法。它的算 法实质是用数值方法解微分方程,通过同时对x和 y各增加一个小增量,计算下一步的x、y值。
边界表示的四连通区域种子填充算法 内点表示的四连通区域种子填充算法 边界表示的八连通区域种子填充算法 内点表示的八连通区域种子填充算法
第3章 基本图形生成算法
1.边界表示的四连通区域种子填充算法
基本思想:从多边形内部任一点(像素)出发,依“左 上右下”顺序判断相邻像素,若其不是边界像素且没有被填 充过,对其填充,并重复上述过程,直到所有像素填充完毕。 可以使用栈结构来实现该算法,算法的执行步骤如下: 种子像素入栈,当栈非空时,重复执行如下三步操作: (1)栈顶像素出栈; (2)将出栈像素置成多边形填充的颜色; (3)按左、上、右、下的顺序检查与出栈像素相邻的 四个像素,若其中某个像素不在边界上且未置成多边形色, 则把该像素入栈。
过各行各列像素中心构造一组虚拟网格线,按直 线从起点到终点的顺序计算直线与各垂直网格线的交 点,然后确定该列像素中与此交点最近的像素。 由图3-5不难看出:若s<t, 则Si比较靠近理想直线,应 选Si;若s≥t,则Ti比较靠近 理想直线,应选Ti。
第3章 基本图形生成算法
令dx=x2-x1,dy=y2-y1 递推公式 :di 1 di 2dy 2dx( yi yi 1 ) di的初值: d1 2dy dx 当di≥0时,选Ti,
第3章 基本图形生成算法
第2章基本图形的生成与计算--直线、圆、椭圆的生成
2a true -1 m
4a true
1 -m
2b false -1/m 1
4b true 1/m -1
数值微分(DDA)法
• 二个规律 (1) |dx| > |dy| 时, |Dx|=1, |Dy|=m |dx|≤|dy| 时, |Dx|=1/m, |Dy|=1 (2) Dx、Dy的符号与dx、dy的符号相同
即求得 Pi+1=Pi+2dy-2(yi+1-yi)dx • 求初值
Pi中代入x1和y1,得初值 P1=2dy-dx
Bresenham画线算法
y=m(xi+1)+b
d1=y-yi
yi+1
D
d2 B
d1
d2=yi+1-y 如果d1-d2>0, yi+1取D(yi+1),否则取C(yi)。
yi
A
C 因此算法的关键在于求出d1-d2的符号。
xi
xi+1 d1-d2=(y-yi)-(yi+1-y)=2y-2yi-1
=2dy/dx(xi+1)-2yi+2b-1
Bresenham画线算法
• 由DDA算法可知:yi+1=yi+m。由于m不一定 是整数,由此式求出的yi也不一定是整 数
• 本算法于1965年由Bresenham提出 • 在直线生成的算法中,Bresenham算法是
最有效的算法之一 • 令 m=Δy/Δx,就0≤m≤1的情况来说明
Bresenham算法
数值微分(DDA)法
void dda_line(int xa,int ya,int xb,int yb,int c) {
第三章-圆弧的生成
P0 ( x0, y0) P , y1) 1 ( x1
画直线的方法 • 方法1:直接求交算法 m y / x
y i ,r round (y i ) (int)( m xi B 0.5)
• 方法2:DDA算法
y i 1,r round (y i 1 ) (int)( yi m 0.5)
Bresenham算法-2
CDC *pDC=GetDC(); Dx=xe-xs; dy=ye-ys; Dxx=dx+dx;dyy=dy+dy; e=-dx; y=ys; for(x=xs;x<=xe;x++) {
pDC->SetPixel(x,y,RGB(0,0,0)); If(e>=0) y=y++,e-=dxx; e+=dyy;
• 方法3:中点算法
y i 1,r
y i ,r y 1 i ,r 当d i 0 当d i 0
1
Bresenham算法
y i 1
yi , y i 1
ei 1
ei k ei k 1
ei 0 ei 0
判别式:
1 1 2 2 d i F ( M ) F ( xi 1, yi ,r ) ( xi 1) ( yi ,r ) R 2 2 2
由圆的正负划分性知:
yi 1,r
yi , r yi , r 1
当di 0 当di 0
1 d i 1 F (x i 2,y i 1,r ) 2 1 2 2 2 (x i 2) (y i 1,r ) R 2 1 2 2 2 ( x 2 ) ( y ) R i ,r i 2 +1+1 1 2 2 2 ( x 2 ) ( y 1 ) R i i , r 2 d i 2x i 3 (x i y i ,r ) 5 d i 2
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。
当我们对直线进行光栅化时,需要在显示器有限个像素中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。
本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法(DDA、中点画线法和Bresenham算法。
3.1.1逐点比较法3.1.2数值微分(DDA)法设过端点P o(x o , y°)、R(X1 , y1)的直线段为L( P0 , R),则直线段L的斜率为—沁生要在显示器显示厶必须确定最佳逼近Z的掃素集合。
我们从L的起点P0的横坐标X o向L的终点R的横坐标X1步进,取步长=1(个像素),用L 的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round( y))作为当前点的坐标。
因为:y i+1 = kX i+1+b= k1X i +b+k x= y i+k x所以,当x =1; y i+1 = y i+k。
也就是说,当x每递增1,y递增k(即直线斜率)。
根据这个原理,我们可以写出DDA( Digital Differential Analyzer) 画线算法程序。
DDA画线算法程序: void DDALi ne(int xO,i nt yO,i nt x1,i nt y1,i nt color){ int x ;float dx, dy, y, k ;dx = x1-x0 ;dy=y1-y0 ;k=dy/dx, ;y=yO;for (x=xO ;x< x1 ;x++){ drawpixel (x, i nt(y+0.5), color);y=y+k;}}注意:我们这里用整型变量color表示像素的颜色和灰度。
举例:用DDA方法扫描转换连接两点P0( 0,0 )和P1( 5,2 )的直线段图3.1.1直线段的扫描转换注意:上述分析的算法仅适用于|k| <1的情形。
在这种情况下,x每增加1,y最多增加1。
当|k| 1时,必须把x, y地位互换,y每增加1, x相应增加1/k。
在这个算法中,y与k必须用浮点数表示,而且每一步都要对y 进行四舍五入后取整,这使得它不利于硬件实现。
动画演示:数值微分画线算法(DDA用QCW方仕想描秒撫直僂梅点应(0.0) 21 (5,2)的直栈徴3.1.3中点画线法假定直线斜率k在0~1之间,当前像素点为(x p,y p),则下一个像素点有两种可选择点P i(X p+1,y p)或P2(X p+1,y p+1)。
若P i 与P2 的中点(x p+1, y p+0.5) 称为M Q为理想直线与x=X p+1垂线的交点。
当M在Q的下方时,则取B应为下一个像素点;当M在Q的上方时,则取P i为下一个像素点。
这就是中点画线法的基本原理。
图3.1.2中点画线法每步迭代涉及的像素和中点示意图下面讨论中点画线法的实现。
过点(x°,y°)、(X1, y1)的直线段L的方程式为F(x, y) =ax+by+c=0,其中,a=y°-y1, b=X1-x°, c=x°y仁xy o,欲判断中点M在Q点的上方还是下方,只要把M代入F (x,y),并判断它的符号即可。
为此,我们构造判别式:d=F(M=F(X p+1, y p+0.5)= a(X p+1)+b(y p+0.5)+ c当d<0时,M在L(Q点)下方,取P2为下一个像素;当d>0时,M在L(Q点)上方,取P i为下一个像素;当d=0时,选P i或P2均可,约定取P i为下一个像素;注意到d是x p, y p的线性函数,可采用增量计算,提高运算效率。
若当前像素处于d 0情况,则取正右方像素R(x p+1, y p),要判下一个像素位置,应计算d i=F(X p+2, y p+0.5)= a(X p+2)+b(y p+0.5)= d+a,增量为a。
若d<0时,则取右上方像素P2(x p+1, y p+1)。
要判断再下一像素,则要计算d2= F(X p+2, y p+1.5)= a(X p+2)+b(y p+1.5)+c=d+a+b ,增量为a+ b。
画线从(X o, y o)开始,d 的初值d o=F(X o+1, y°+0.5)= F(X o, y°)+a+0.5b,因F(x°, y°)=0,所以d°=a+0.5b。
由于我们使用的只是d的符号,而且d的增量都是整数,只是初始值包含小数。
因此,我们可以用2d代替d来摆脱小数,写出仅包含整数运算的算法程序。
中点画线算法程序:void Midpoint Line (int x0,int y0,int x1, int y1,int color){ int a, b, d1, d2, d, x, y ;a=y0-y1 ;b=x1-x0 ;d=2*a+b;d1=2*a ;d2=2* (a+b);x=x0 ;y=y0;drawpixel(x, y, color);while (x<x1){ if (d<0) {x++ ;y++;d+=d2; }else {x++ ;d+=d1;}drawpixel (x, y, color);} /* while */} /* mid PointLine */举例:用中点画线方法扫描转换连接两点P0(0,0 )和P1 (5,2 )的直线段。
a=y0-yi=-2; b=xi-x0=5; d0=2*a+b=1;d 仁2*a=-4;d2=2*(a+b)=6 ,图3.1.3中点画线法问题1:若上述算法往下取二步(i=2),则算法和像素的取法将变成怎样? 问题2:与DDA 法相比,中点法的优点是什么?动画演示:中点画线算法=2*a=4 :^2=2*(a+b)3.1.4 Bresenham 算法Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换算法。
仍然假定直线斜率在0~1之间,该方法类似于中点法,由一个误差项符号决定下一个像素点。
算法原理如下:过各行各列像素中心构造一组虚拟网格线。
按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的巧妙之处在于采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求像素。
如图2.1.4所示,设直线方程为y i+i=y i+k(x i+i-xj+k。
假设列坐标像素已经确定为X i,其行坐标为y i。
那么下一个像素的列坐标为X i + 1,而行坐标要么为y i,要么递增1为y i + 1。
是否增1取决于误差项d的值。
误差项d的初值d o =0,x坐标每增加1,d的值相应递增直线的斜率值k,即d = d+ k。
一旦d> 1, 就把它减去1,这样保证d在0、1之间。
当d>0.5时,直线与垂线x=X i + 1交点最接近于当前像素(x,y i)的右上方像素(X i + 1, y i + 1);而当d<0.5时,更接近于右方像素(X i + 1, y i)。
为方便计算,令e = d-0.5 , e的初值为—0.5,增量为k。
当e》0时,取当前像素(X i, y i)的右上方像素(X i + 1, y i + 1);而当e<0 时,取(X i, y i)右方像素(X i + 1, y i)。
图3.1.4 Bresenham算法所用误差项的几何含义O Brese nham画线算法程序:void Brese nhamli ne (int x0,i nt y0,i nt x1, int y1,i nt color) { int x, y, dx, dy ;float k, e;dx = x1-x0 ;dy = y1- y0 ;k=dy/dx ;e=-0.5 ;x=x0, ;y=y0;for (i=0 ;i<dx ;i++){ drawpixel (x, y, color);x=x+1 ;e=e+k;if (e 0){ y++ ;e=e-1;}}举例:用Bresenham方法扫描转换连接两点P0 (0,0 )和P1 (5,2 )的直线}图 3.1.5 Bresenham 算法上述Bresenham算法在计算直线斜率与误差项时用到小数与除法。
以改用整数以避免除法。
由于算法中只用到误差项的符号,因此可作如下替换: 2*e*dx 。
改进的Bresenham画线算法程序:void In terBrese nhamli ne (int x0,i nt y0,i nt x1, int y1,i nt color){ dx = x1-x0, ;dy = y1- y0, ;e=-dx;x=x0 ;y=y0;for (i=0; i<dx; i++){drawpixel (x, y, color);x++ ;e=e+2*dy;if (e 0) { y++; e=e-2*dx;}}}动画演示:Brese nham画线算法:}禺民也s 方诫和無转辕直複厨 A PO (a)牝刊(5^)迢直找段e=d 0.5, d=d+k P k=dy/dx.□e^QH f 取廿前很秦的右上苏車泰折下一十魚素3.2 圆弧的扫描转换算法这一节我们来讨论圆弧的扫描转换算法。
3.2.1圆的特征圆被定义为到给定中心位置(x c ,y c )距离为r 的点集。
圆心位于原点的圆 有四条对称轴x=0,y=0,x=y 和x=-y 。
若已知圆弧上一点(x,y),可以得到其关于 四条对称轴的其它7个点,这种性质称为圆的八对称性。
因此,只要扫描转换八 分之一圆弧,就可以求出整个圆弧的像素集。
显示圆弧上的八个对称点的算法:void CirclePoi nts(i nt x,i nt y,i nt color) { drawpixel(x,y,color); drawpixel(y,x,color);drawpixel(-x,y,color); drawpixel(y,-x,color); drawpixel(x,-y,color); drawpixel(-y,x,color); drawpixel(-x,-y,color); drawpixel(-y,-x,color);322中点画圆法如果我们构造函数F(x, y)=x 2+y 2-氏,贝U 对于圆上的点有F(x, y)=0 ,x yf?0 V0,5 4).51 0-(J. 5 -0. 12 ]0.3 -0.73 1-0. 7 -0.3O -•为初給点O f 终止点■1 2 0, 1 ■0.95 2-0.9-0. 5• 一为当前鞋素点 •一为F —亍氟素点对于圆外的点有F(x,y)>0 ,对于圆内的点F(x, y)<0。