第3章生成算法
第三章 生成直线和圆弧的算法

Bresenham画线算法
设图中xi列上已用(xi,yir)作为表示直线的点, 又设B点是直线上的点,其坐标为(xi+1,yi+1),显然 下一个表示直线的点( xi+1,yi+1,r)只能从图中的C 或者D点中去选。设A为CD边的中点。 若B在A点上面 则应取D点作为( xi+1,yi+1,r),否则应取C点。
P2 Q
P=(xp,yp) P1
中点画线法
• 画线从(x0, y0)开始,d的初值 d0=F(x0+1, y0+0.5)= a(x0 +1)+b(y0 +0.5)+c = F(x0, y0)+a+0.5b = a+0.5b 由于只用d 的符号作判断,为了只包含整数运算, 可以用2d代替d来摆脱小数,提高效率。
数值微分(DDA)法
• 增量算法:在一个迭代算法中,如果每 一步的x、y值是用前一步的值加上一个 增量来获得,则称为增量算法。 • DDA算法就是一个增量算法。
数值微分(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; } }
一逐点比较法
算法: 1、偏差计算 1)一般公式
α β
A(xA, xA)
M(xM, xM)
• 偏差
yM y A d = tg β − tg α = − xM x A y M x A − y A xM = xM x A
精品文档-计算机组成与系统结构(裘雪红)-第3章

(4) 运算结果为补码表示。
第3章 运算方法与运算器
10
2. 溢出判断 1) 溢出的概念 例3.4 有两个定点整数63和85,利用补码加法求63+85=? 解 根据题意,用8位二进制补码表示63和85:
第3章 运算方法与运算器
11
例3.5 设正整数X=+1000001,Y= +1000011,若用8位补 码表示,则[X]补=01000001,[Y]补=01000011,求[X+Y]补。
第3章 运算方法与运算器
15
(2) 进位判决法。若Cn-1为最高数值位向最高位(符号位)的 进位,Cn表示符号位的进位(即进位标志CF),则判别溢 出的逻辑表达式为
(3-4)
OF=Cn-1⊕Cn
溢出判定如表3.1所示。在例3.6的运算过程中,Cn-1为0而 Cn为1 ,故Cn-1⊕Cn=1,表示运算结果有溢出。
第3章 运算方法与运算器
28
图 3.3 四位先行进位链电路
第3章 运算方法与运算器
29
5. BCD数加法器 1) 8421 BCD码
第2章中已详细地介绍了BCD码。在所描述的几种BCD码中, 计算机中应用最广泛的是8421 BCD码。8421 BCD码只利用了四 位二进制编码的0000~1001这十种来表示十进制数的0~9,剩余的
(3-6)
第3章 运算方法与运算器
19
3. 一位全加器的实现
设一位全加器的输入分别为Xi和Yi,低一位对该位的进位 为Ci, 全加器的结果和向高一位的进位分别用Zi和Ci+1表示, 则 一位全加器所实现的逻辑表达式如下:
(3-7)
(3-8)
第3章 运算方法与运算器
20
实现上述逻辑功能的一位全加器的逻辑电路及其框图分别
Bresenham 画圆算法_计算机图形学实用教程(第3版)_[共3页]
![Bresenham 画圆算法_计算机图形学实用教程(第3版)_[共3页]](https://img.taocdn.com/s3/m/5c9f4c2e0242a8956aece48f.png)
55 01e r =− (3-39) 这样,由于判别式的初值为整数,增量也为整数,因此判别式始终为整数,即中点画圆算法可用整数加减运算来计算圆周上所有像素的位置。
中点画圆算法的描述如下。
(1)输入圆的半径r 和圆心坐标(x c , y c ),先计算以原点为圆心、r 为半径的圆周上的点,令初始点为00(,)(0,)x y r =。
(2)求初始判别式d ,1d r =−。
(3)在每一个x n 的位置,从n = 0开始,进行下列检测:如果d <0,则圆心在原点的圆的下一个点为(x n +1, y n ),且23n d d x =++;否则,圆的下一个点为(x n +1, y n −1),且2()5nn d dx y =+−+。
(4)确定(x n+1, y n +1)在其余7个八分圆中的对称点位置。
(5)将计算出的每个像素位置(x , y )平移到圆心位于(x c , y c )的圆的轨迹上,即分别沿水平和垂直方向平移x c 和y c ,平移后的坐标值为(x', y' ),c x x x ′=+,c y y y ′=+。
(6)重复第(3)至(5)步,直到x ≥y 时为止。
下面以半径r = 10、圆心在原点的圆为例来说明按上述算法计算第一八分圆上的像素位置的过程。
首先求出初始点(x 0, y 0) = (0, 10),判别式d 0 = 1−r =1−10 = −9,其后续的判别式计算结果和生成的像素位置如表3-1所示。
经过计算最后生成的从(x 0, y 0)到(x 7, y 7)第一八分圆上的8个像素位置如图3-8所示。
表3-1以原点为圆心r =10的第一八分圆的判别式的值和像素位置 n d 2x n + 32x n − 2y n + 5 (x n , y n ) 0 −9 3- (0, 10) 1 −6 5- (1, 10) 2 −1 7- (2, 10) 3 6 -−9 (3, 10) 4 −3 11- (4, 9) 5 8 -−3 (5, 9) 6 5 -1 (6, 8) 7 6 - - (7, 7)3.2.4 Bresenham 画圆算法与中点画圆算法一样,Bresenham 画圆算法也是先考虑圆心在原点、半径为r 的第一四分圆的生成,即取(0, r )为起点,按顺时针方向生成第一四分圆,然后根据圆的对称特性通过对称变换生成整圆。
头歌数据结构与算法课程设计-算法与竞赛(第3章)-C++与算法基础二

头歌数据结构与算法课程设计-算法与竞赛(第3章)-C++与算法基础⼆Algorithm 中⽂意思是算法,是⼀个计算的具体步骤,常⽤于数据处理、计算以及⾃动推理。
它作为 C++ 标准模版库 STL 中最重要的头⽂件之⼀,其提供了⼤量⾮成员模版函数,例如排序操作、⼆分查找操作、集合操作以及堆操作等。
同时可以通过迭代器或指针访问任何对象序列,例如 STL 容器数组或实例。
更多的了解请参考。
本实训主要设置了四个关卡:第⼀关和第⼆关介绍了 Algorithm 中的⼆分搜索操作 binary_search 及其相关搜索操作;第三关是修改序列操作 Modifying sequence operations ;第四关讲的是⾮修改序列操作 Non-modifying sequence operations 。
最后在每个关卡都设置了实例,考察学员对所讲内容的理解和在线编程能⼒。
第1关:⼆分查找:在N个⽆序整数⾥⾯查找M个指定整数任务描述本关任务:给定包含 N 个整数的⽆序序列 S(a1,a2,..,aN),以及 M 次查询序列 Q(b1,b2,..,bM),判定 bj是否在序列 S 中。
相关知识为了完成本关任务,你需要掌握:1.解题思路,2.快速排序算法,3.⼆分查找算法。
解题思路本关卡问题清晰,解法简单:对于每次查询bj,在序列S中遍历ai是否等于bj。
虽然该解法实现简单,但是执⾏效率低,运算复杂度⾼O(N×M)。
⾼效解法:⾸先运⽤快速排序算法,将⽆序序列变为有序(升序),然后对每次查找操作,使⽤⼆分查找算法判断元素是否存在。
该解法实现稍微有点复杂,但是执⾏效率⾼,运算复杂度低O(N×logN+M×logN)。
快速排序算法快速排序算法的背景和原理前⾯已有很多实训介绍过了,为了⽅便实现,⼀般使⽤ algorithm 中模板函数 sort ,请认真参考的第三个关卡,之后的实训将不再对sort进⾏讲解。
第3章自适应波束形成及算法

第3章自适应波束形成及算法(3.2自适应波朿形成的几种典型算法)3.2自适应波朿形成的几种典型算法自适应波束形成技术的核心内容就是自适应算法。
U前已提出很多著名算法,非盲的算法中主要是基于期望信号和基于DOA的算法。
常见的基于期望信号的算法有最小均方误差(MMSE)算法、小均方(LMS)算法、递归最小二乘(RLS)算法,基于DOA算法中的最小方差无畸变响应(MVDR)算法、特征子空间(ESB)算法等叫3.2.1基于期望信号的波束形成算法自适应算法中要有期望信号的信息,对于通信系统来讲,这个信息通常是通过发送训练序列来实现的。
根据获得的期望信号的信息,再利用MMSE算法、LMS算法等进行最优波束形成。
1.最小均方误差算法(MMSE) 最小均方误差准则就是滤波器的输出信号与需要信号之差的均方值最小,求得最佳线性滤波器的参数,是一种应用最为广泛的最佳准则。
阵输入矢量为:兀(“)=[召(“),...,心(n)f(3-24)对需要信号d(n)进行估计,并取线性组合器的输出信号y(”)为需要信号〃(“)的估计值d(n)f即d(n) = y(n) = w H x(n) = x' (n)w(3-25)估计误差为:e(〃)= = d(n)-w n x(n)(3-26)最小均方误差准则的性能函数为:§ = £{le⑴鬥(3-27)式中纠}表示取统计平均值。
最佳处理器问题归结为,使阵列输出y(n) = w T X(n)与参考信号〃⑴的均方误差最小,即:MinE{ I ⑴门(3-28)式(3-28)也就是求最佳权的最小均方准则。
由式(3-26)〜(3-28)得:§ = E{ I e(/) I2 ) = E{e(ii)e\n)} =E{ I d(n)f}-2 Re[vr7r v J + w HR^w(3-29)其中,Re表示取实部,并且:= E[x(n)x n (n)](3-30)为输入矢量x(“)的自相关矩阵。
第3章 图形的基本算法

dy s t 2 ( x i 1 1) 2 y i 1 1 dx
dx(s t ) 2( xi 1 dy y i 1 dx) 2dy dx
因dx>0,所以我们可以以dx(s-t) 的正负作 为选择点的依据。若令其为di,则
d i 2( xi 1 dy y i 1 dx) 2dy dx
若s<t,则Si较靠近理论直线,应选Si,y 不变; 若s>t,则Ti较靠近理论直线,应选Ti,y 增1。 现在需要一个判别式,来判断每一步是选 Ti还是选Si。下面导出Bresenham 算法的 判别式。
判别式的导出
设一直线段由(x1,y1)至(x2,y2),(其中 y2>y1,x2>x1)则直线方程可表示为
怎样选择直线的最佳光栅位置(象素点), 是Bresenham 算法追求的目标。为此,算 法根据直线的斜率在计长方向(x或y)上, 每次都递增一个单位步长即一个象素单位, 另一个方向的增量为0或1。这种算法的巧 妙之处是只需检查判别式的符号即可,而 且计算量很小,只进行整型数计算,不必 做舍入操作。
直线的近似表示
第三章 图形的基本算法
本章内容
3.1 图形的表示 3.2 图形模式与坐标系 3.3 直线的扫描转换 3.4 圆的生成算法 3.5 多边形的填充
3.1 图形的表示
计算机图形学是一门复杂而又多样化的技 术。要想了解这项技术必须把它分成几个 易于操作的部分。图形是计算机图形学的 关键概念,处理图形我们应考虑以下问题: 1. 如何在计算机中表示图形? 2. 如何准备图形的数据? 3. 如何显示准备好的图形? 4. 如何实现人与图形的交互?
这里,图形是一个广义的概念,凡是可 以在图形设备上输出的点、线、文本等 的集合都可以称为是图形。
chap3 算法与基本程序设计
C语言程序设计
第3章 算法与基本程序设计
3.2.3 I/O格式--格式字符
1 2 3 4 5 6 7 8 9 10 %d %o %x、%X %u %c %s %f %e、%E %g %% 十进制格式 八进制格式 十六进制格式 无符号的十进制格式 一个字符格式 字符串格式 实数格式 指数格式 e和f中较短一种格式 百分号本身
2
C语言程序设计
第3章 算法与基本程序设计
3.1 问题引入
#include <stdio.h> main( ) { double x; int a; scanf(“%lf”,&x); x=x*100+0.5; a=x; x=a/100.0;//why? printf(“%f”,x);}
3
试一下运行 时结果
特
束
C语言程序设计
第3章 算法与基本程序设计
3.2.1 字符数据的输入和输出
例: 将输入的大写字母转变为小写字母输出。
#include <stdio.h> main( ) { char ch; ch=getchar(); ch-=32; putchar(ch); }
7
运行时: a 结果: A
24
C语言程序设计
第3章 算法与基本程序设计
3.2.4 格式输入函数 scanf
可以按指定格式从键盘读入任意类型的数据。 格式:scanf( 格式字符串, 地址参数列表 );
格式 适用类型 格式 适用类型 变量的地址列表,可通过取地址运算符 &
%d获取变量地址 int %f float
%ld
%u %lu
123.456001, □□□□123.46, 123.46, 123.46
有序边表算法_计算机图形学实用教程(第3版)_[共3页]
65 3.4.3 有序边表算法1.简单的有序边表算法由于3.4.2小节介绍的一般多边形的扫描线填充算法是建立在按扫描顺序对多边形的边与扫描线交点进行排序的基础上的,所以称为有序边表算法。
将简单的有序边表算法描述如下。
(1)数据准备。
① 求出多边形各条边与中心扫描线的交点,并将各交点坐标(x , y +0.5)存入表中。
② 按扫描线以及扫描线上交点x 值的递增顺序对该表中存放的交点进行排序,形成有序边表。
(2)扫描转换。
① 按(x 1, y 1)和(x 2, y 2)成对地取出有序边表中的交点坐标值,表的构造保证有y = y 1 = y 2及 x 1≤ x 2。
② 在扫描线y 上激活那些x 的整数值满足x 1≤ x +0.5≤ x 2关系的像素。
2.简单有序边表算法的效率问题及解决方法简单的有序边表算法存在3个问题:一是需要生成一个很大的交点表,而且需要对整张表排序;二是求交计算中含有乘除法运算,运算复杂;三是交点计算的次数多,这是因为在计算交点时,相当于是把多边形的所有边放在一个表中,按顺序依次取出,计算该边与当前扫描线的交点,而事实上并非所有的边都与当前扫描线有交点,因此增加了许多不必要的求交计算量。
可见,求交和交点排序的计算量大是影响该算法效率的最主要的因素,为了提高算法的效率,应该尽量减少和简化求交计算。
那么如何减少和简化求交计算呢?采用活性边表的有序边表算法可以有效解决这个问题。
采用活性边表的有序边表算法与简单有序边表算法的不同之处在于,它对每条扫描线都建立一个活性边表。
那么什么是活性边和活性边表呢?我们把与当前扫描线有交点的边,称为活性边,而把用于存储活性边的表称为活性边表。
在每一个活性边表中,活性边按与扫描线交点x 坐标递增的顺序存放在一个链表中。
因此,采用活性边表后,不仅节省了求交的时间,而且还节省了交点排序的时间。
下面的问题是,在活性边表中应该存储活性边的哪些信息呢?由于存储活性边的目的是要保证存储的这些信息对计算活性边与扫描线的交点有用。
《计算机算法设计与分析》第三章动态规划法
发展历程及现状
发展历程
动态规划的思想起源于20世纪50年代,由美国数学家Richard Bellman提出。随着计 算机科学的发展,动态规划在算法设计和分析领域得到了广泛应用和深入研究。
第六章
总结与展望
动态规划法在计算机科学中重要性
高效求解最优化问题
动态规划法通过把原问题分解为相对简单的子问题,并保存子问题的解,避免了大量重复计算,从而高效地求解最优化问题。
广泛应用
动态规划法在计算机科学、经济学、生物信息学等领域都有广泛应用,如背包问题、最短路径问题、序列比对问题等。
提供算法设计框架 动态规划法不仅为解决特定问题提供了有效方法,而且为算法设计提供了一个通用框架,有助于理解和设 计更复杂的算法。
现状
目前,动态规划已经成为计算机算法设计和分析领域的重要工具之一。在实际应用 中,许多复杂的问题都可以通过动态规划的方法得到有效的解决。同时,随着计算 机技术的不断发展,动态规划的应用领域也在不断扩展。
第二章
动态规划法基本原理
最优子结构性质
在动态规划法中, 子问题之间是相互 独立的,即一个子 问题的求解不会影 响到其他子问题的 求解。这使得动态 规划法能够避免重 复计算,提高算法 效率。
学习相关算法和技术
学习与动态规划法相关的其他算法 和技术,如贪心算法、分治法等, 以便在实际问题中灵活应用。
关注最新研究进展
关注计算机科学和算法设计领域的 最新研究进展,了解动态规划法的 新发展和应用,保持对新技术的敏 感性和好奇心。
THANKS
感谢观看
基本思想
第3章 算法与输入输出
什么是算法? 什么是算法
为解决一个问题而采用的方法和步骤称为算法。 为解决一个问题而采用的方法和步骤称为算法。 对同一个问题,可以有不同的算法,但算法有优劣 同一个问题,可以有不同的算法, 之分,有的算法步骤少,有的算法步骤多。 之分,有的算法步骤少,有的算法步骤多。我们希望 得到方法正确,步骤少的算法。 得到方法正确,步骤少的算法。 种工具, 算法语言只是一 种工具,为实际问题设计算法才 是程序设计的核心。 是程序设计的核心。 因此,为了有效地进行解题, 因此,为了有效地进行解题,不仅需要保证算法 正确,还要考虑算法的质量,选择合适的算法。 正确,还要考虑算法的质量,选择合适的算法。
图3.5是当型循环的应用例子,图3.6是直到型循 环的应用例子。
图3.4
图3.5
图3.6
图3.5和图3.6的作用都是打印5个数:1,2,3, 4,5。可以看到, 对同一个问题既可以用当型循环 来处理,也可以用直到型循环来处理。 以上三种基本结构,有以下共同特点:
(1) 只有一个入口。 (2) 只有一个出口。请注意,一个菱形判断框 有两个出口,而一个选择结构只有一个出口。不 要将菱形框的出口和选择结构的出口混淆。 (3) 结构内的每一部分都有机会被执行到。对 每一个框来说,都应有一条从入口到出口的路径 通过它。图3.7中没有一条从入口到出口的路径通 过A框。 (4) 结构内不存在“死循环”(无终止的循环)。 图3.8就是一个死循环。
② 直到型(Until型)循环 见图3.4(b)。它的功能是先执行A框,然后判 断给定的p2条件是否成立,如果p2条件不成立, 则再执行A,然后再对p2条件作判断,如果p2条 A p2 p2 件仍然不成立,又执行A……如此反复执行A, 直到给定的p2条件成立为止,此时不再执行A, 从b点脱离本循环结构。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第三章 基本图形生成算法(书P107)本章讲直线、圆弧的生成及多边形填充的算法。
一.概念◆ 基本图形元素:指构成图形的基本元素,例如:点、直线、圆弧等。
◆ 象素:屏幕上的光点,它是最小的屏幕显示单位,其大小取决于显示器的尺寸和分辨率。
用坐标表示。
◆ 生成图形:确定最佳逼近于图形的象素,用图形颜色对象素进行写操作。
这称为图形的扫描转换。
◆ 生成直线的质量要求:①直线要直。
②直线的端点要准确,即无定向性和断裂情况。
③直线的亮度、色泽均匀。
④画线的速度要快。
二.直线生成算法下面介绍画一个象素宽的直线的三种常用算法:1.数值微分法(DDA )所谓DDA 法就是先计算出直线的斜率K=xy ∆∆(其中Δy =y 1- y 0 , Δx= x 1- x 0 ,而(x 0 ,y 0)和(x 1 ,y 1)分别是直线的起点和终点),然后从直线的起点开始,确定最佳逼近于直线的y 坐标,让x 从起点到终点变化,x 每递增1,计算对应的y 坐标。
令y=kx+b, 当x i+1 =x i +Δx 时y i+1=kx i+1+b=k(x i +Δx)+b= kx i +Δxk+b= kx i +b+Δxk= y i +Δxk= y i +k算法如下:DDAline(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{int x;float dx,dy,k,y;dx=x1-x0;dy=y1-y0;k=dy/dx; 注意+0.5y=y0;for (x=x0;x<=x1;x++){putpixel (x,(int)(y+0.5),color); y=y+k;} 网格的交点表示象素}注意上述算法仅适用于│k│<=1的情况,见程序linedda.c 。
若│k│>1,必须把x,y 的角色互换,y 每增加1,x 相应增加1/k 。
书P108 的算法(DDA.c )综合了各种情况。
2.中点画线法则y方向上的增量只能是0或1。
如图中假设P与直线最接近的象素已确定,其坐标为(x p ,y p),那么下一个与直线最近的象素只能是P1(x p +1¸ y p)或P2(x p +1¸ y p+1)两者之一。
用M表示P1与P2的中点,即M=(x i +1¸ y i+0.5)。
若M在直线上方,则取P1 ;否则取P2。
这就是中点画线法的基本原理。
下面讨论中点画线法的实现。
设直线的起点和终点分别为(x0 ,y0)和(x1 ,y1),则直线方程为:F (x,y)= y-kx-b=0 其中,k为斜率,b为截距。
对于直线上的点F(x,y)=0; 对于直线上方的点F(x,y)>0; 对于直线下方的点F(x,y)<0。
因此要判断上图中Q(直线与垂直线的交点)在中点M的上方还是下方,只要把M代入F(x,y),并判断它的符号。
即F(M)=F(xi +1,yi +0.5)= yi +0.5–k(xi +1)–b,当F(M)<0时,M在直线的下方(即在Q的下方),故应取右上方的P2作为下一个象素。
而当F(M)>0时,则应取正右方的P1作为下一个象素。
当F(M)=0时,二者一样合适,可任选一个。
算法如下:MidpointLine(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{ int x,y;float mid,k,b;k=(y1-y0)/(x1-x0);b=y0- k* x0;x=x0;y=y0;putpixel(x,y,color);do{ mid= y+0.5– k*(x+1)-b;if (mid<0) y++;x++;putpixel(x,y,color);} while (x<x1);}注:0<=k<=1。
为提高运算效率,可计算出mid的递推关系式,推导过程如下:在mid>=0的情况下,取正右方象素P1,欲判断再下一个象素应取那个,递推关系式为:F(x i+2 ,y i+0.5)= y i +0.5 -k(x i +2)-b= y i +0.5-k(x i +1)-b-k;= mid-k;在mid<0的情况下,则取右上方象素P2,要判断再下一个象素,则要计算F(x i+2 ,y i+1.5)= y i +1.5-k(x i +2)-b= y i +0.5-k(x i +1)-b+1-k=mid+1-k;F(M)的初始值为:F(x 0 +1,y 0 +0.5)= y 0 +0.5-k (x 0 +1)-b= y 0 -kx 0 - b + 0.5-k= F(x 0 ,y 0)+0.5-k=0.5-k由于(x 0 ,y 0 )在直线上,故F(x 0 ,y 0 )=0。
这样算法改为:MidpointLine(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{ int x,y,mid,dx,dy,d_up,d_down;dy=y1-y0;dx=x1-x0;mid=dx-2*dy; /*mid 应该为0.5-k , 为了摆脱实数运算扩大2dx 倍*/d_up =2*dx - 2*dy;d_down = -2*dy; /*注意扩大了2dx 倍*/x=x0;y=y0;while (x<=x1){ putpixel(x,y,color);x++;if (mid<0) {y++;mid=mid+d_up;}else mid=mid+ d_down;}}作业1:用中点画线法光栅化一条连接两点(0,0)和(5,3) 的一条直线。
3.Bresenham 画线算法Bresenham 也是通过在每列象素中确定与理想直线最近的象素来进行画线的。
该算法是最为流行的画线方法,它将直线方程转换成一个迭代过程。
与中点画线法类似,只是判中点的方法不同。
如下图所示,只要判直线与垂线的交点到网格线的距离d ,当d>0.5往右上方走一步(当x i+1 =x i +1时, y i+1 =y i +1) ;当d<0.5时,往正右方走一步(当x i+1 =x i +1时, y i+1 =y i )。
从上图可得:⎩⎨⎧>-+<+=+时当时当5.015.01i ii i i d k d d kd d 为计算方便,令e=d-0.5, 所以有:⎩⎨⎧>-+=--+<+=-+=+时当时当015.0105.01i i i i i i i e k e k d e k e k d e初始的e 0= -0.5. 即有:⎪⎩⎪⎨⎧⎩⎨⎧>+<=+=++)()(010111i i i i i i i e y e y y x x这种方法比中点画线法简单。
算法如下:BrsenhamLine(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{int x,y,dx,dy,i;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++){ putpixel(x,y,color);x++; e=e+k;if (e>0){y++;e=e-1;}}}此算法适用于0<=k<=1。
此算法中用到除法,改进后见P113。
作业2:从键盘输入封闭多边形的端点坐标(任意斜率),试分别采用中点画线算法和Bresenham 算法画出该多边形。
(上机实现)三.圆的生成算法画圆的方法很多。
在本节中,主要讨论三种生成圆的算法一般方法有:直角坐标法:根据圆的方程x 2+y 2=R 2 来生成,如x i+1=x i +1, y=(int)(212+-i x R +0.5)。
极坐标法:用圆的极坐标方程(参数方程)圆x2+y2=R2的参数方程为:x=R*cosθy=R*sinθ 0<=θ<=360#include<graphics.h>#include<math.h>#define pi 3.14159main(){int driver,mode,x,y,maxx,maxy,r=60;float t;driver=DETECT;initgraph(&driver,&mode,"");maxx=getmaxx();maxy=getmaxy();line(0,maxy/2,maxx,maxy/2);line(maxx/2,0,maxx/2,maxy);for (t=0;t<=2*pi;t+=0.01){ x=maxx/2+r*cos(t);y=maxy/2+r*sin(t);if (t==0)moveto(x,y);lineto(x,y);}getch();closegraph();}1.绘圆的正负法设所要画的圆的圆心在(a,b),半径为R,则圆的方程为:F(x,y)= (x- a)2 +(y- b)2-R2=0,当点(x,y)在圆内时,F(x,y)<0;当点(x,y)在圆外时,F(x,y)>0。
现以画第一四分之一圆弧(第一象限)为例说明正负画圆算法。
设P i (x i,y j)是已求得的象素点,那么找下一个点P i+1的原则为:当F(x i,y j)<=0时,取x i+1 = x i +1,y i+1 = y i当F(x i,y j)>0时,取x i+1 = x i,y i+1 = y i–1F(x i,y j)<0说明P i在圆内,要向右走一步得P i+1,即向圆外方向走去;F(x i,y j)>0, 说明P i在圆外,要向下走一步得P i+1,即向圆内方向走去。
向圆内或圆外走是取决于F(x,y)的正负,因此称为正负法。
设F(x i,y j)的值已经算出,在计算F(x i+1,y j+1)时有下列两种情况:当F(x i,y j)<=0时,F(x i+1,y j+1)= F(x i+1,y j)=(x i+1-a)2+(y i-b)2–R2=(x i-a)2+(y i-b)2–R2 +2(x i -a)+1= F(x i,y j) +2(x i -a)+1当F(x i,y j)>0时,F(x i+1,y j+1)= F(x i,y j-1)=(x i-a)2+(y i-1-b)2–R2=(x i-a)2+(y i-b)2–R2 -2(y i -b)+1= F(x i,y j)- 2(y i -b)+1具体算法如下:PMcircle(a,b,r,color)int a,b,r,color;{int x,y,f;x=a,y=b+r;f=0;while (x<=a+r){putpixel(x,y,color);if(f<=0){f+=2*(x-a)+1;x++;}else {f=f-2*(y-b)+1;y--;}}}见程序circle1.c下面只讨论圆的中心在坐标的原点(0,0),半径为整数R的圆,圆的方程为x2 +y2= R2。