椭圆中点Bresenham算法

合集下载

中点bresenham算法过程

中点bresenham算法过程

中点Bresenham算法是一种用于计算在直线上的格点的算法。

它是由Bresenham在1965年提出的,是一种高效的计算机图形学算法,通常用于直线、圆、椭圆等形状的绘制。

通过这篇文章,我们将详细介绍中点Bresenham算法的过程。

1. 背景知识在计算机图形学中,我们经常需要在屏幕上绘制直线、圆、椭圆等形状。

而计算机屏幕上的图像是由像素组成的,因此我们需要一种算法来计算出这些形状上的像素坐标,从而进行绘制。

中点Bresenham算法就是用来解决这个问题的。

2. 中点Bresenham算法的原理中点Bresenham算法的原理是通过巧妙的数学推导,找到离直线最近的像素点,从而确定需要绘制的像素坐标。

该算法通过利用误差项来判断下一个像素点的位置,具有高效、简洁的特点。

3. 中点Bresenham算法的过程中点Bresenham算法的过程可以分为以下几个步骤:3.1 初始化变量:首先需要确定直线的起点和终点,并初始化相关变量,如起点坐标(x0, y0)、终点坐标(x1, y1)、误差项d和增量变化量dx、dy等。

3.2 计算斜率k和误差项初始值:通过计算直线的斜率k,并根据斜率确定误差项的初始值。

3.3 循环计算像素点的坐标:根据误差项的大小,确定下一个像素点的位置,并更新误差项的值,直到绘制完整条直线。

4. 中点Bresenham算法的优势* 算法简洁高效:中点Bresenham算法通过简单的数学计算,即可确定直线上的像素坐标,避免了直接计算斜率导致的浮点数运算,因此在计算速度上具有较大优势。

* 适用范围广泛:中点Bresenham算法不仅适用于直线,还可以用于绘制圆、椭圆等图形,具有良好的通用性。

5. 中点Bresenham算法的应用中点Bresenham算法广泛应用于计算机图形学中的直线、圆、椭圆等图形的绘制。

其高效、简洁的特点使得它成为了计算机图形学中不可或缺的算法之一。

中点Bresenham算法是计算机图形学中的重要算法之一,通过巧妙的数学计算,实现了高效、简洁的直线绘制。

案例4椭圆中点Bresenham算法

案例4椭圆中点Bresenham算法

总结
图4-4 绘制椭圆的外接矩形
程序代码
(2)四分法画椭圆子函数 void CTestView::EllipsePoint(double x, double y ,CDC *pDC) { CP2 pc=CP2((p0.x+p1.x)/2.0,(p0.y+p1.y)/2.0); //椭圆中心坐标 COLORREF clr=RGB(0,0,255); //定义椭圆的颜色 pDC->SetPixelV(Round(x+pc.x),Round(y+pc.y),clr); pDC->SetPixelV(Round(-x+pc.x),Round(y+pc.y),clr); pDC->SetPixelV(Round(x+pc.x),Round(-y+pc.y),clr); pDC->SetPixelV(Round(-x+pc.x),Round(-y+pc.y),clr); }
(1)根据鼠标选择的矩形对角点计算椭圆的长半轴a和短半轴b。 (2)定义椭圆当前点坐标x,y、定义中点误差项d1与d2、定义像素点颜色clr。 (3)计算 ,x=0,y=b,clr=RGB(0,0,255)。 (4)绘制点(x,y)及其在四分椭圆中的另外3个对称点。 (5)判断d1的符号。若d1<0,则(x,y)更新为(x+1,y),d1更新为d1+b2 (2x+3);否则(x,y)更新为(x+1,y-1),d1更新为d1+b2(2x+3)+ a2(-2y+2)。 (6)当 时,重复步骤(4)与(5),否则转到步骤(7)。 (7)计算下半部分d2的初值: 。 (8)绘制点(x,y)及其在四分椭圆中的另外3个对称点。 (9)判断d2的符号。若d2<0,则(x,y)更新为(x+1,y-1),d2更新为 d2+b2(2x+2)+a2(-2y+3);否则(x,y)更新为(x,y-1),d2更新 为d2+a2(2y+3)。 (10)如果y≥0时,重复步骤(8)和(9),否则结束。

计算机图形学实验03

计算机图形学实验03

计算机图形学实验03
《计算机图形学》实验报告
圆(椭圆)的生成算法
一、实验教学目标与基本要求
1.实现圆的生成算法;
2.实现椭圆的生成算法;
二、实验课程内容 (2学时)
1.写出完整的圆的Bresenham生成算法;
2.写出完整的椭圆的中点生成算法;
三、算法思想
1.圆的Bresenham生成算法:
如果我们构造函数 F(_,y)=_+y-R,则对于圆上的点有F(_,y)=0,对于圆外的点有F(_,y)_gt;0,对于圆内的点F(_,y)_lt;0 。

与中点画线法一样,构造判别式:d=F(M)=F(_p+1,yp-0.5)=(_p+1)+(yp-0.5)-R。

若d_lt;0,则应取P1为下一象素,而且再下一象素的判别式为:
222d=F(_p+2,yp-0.5)=(_p+2)+(yp-0.5)-R=d+2_p+3
若d≥0,则应取P2为下一象素,而且下一象素的判别式为:
d=F(_p+2,yp-1.5)=(_p+2)+(yp-
1.5)-R=d+2(_p-yp)+5我们这里讨论的第一个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R。

为了进一步提高算法的效率,将上面的算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。

2.椭圆的中点生成算法:
椭圆中点生成算法是将椭圆在第一象限中分为两个部分:
1)对于斜率绝对值小于1的区域内在_方向取单位量;
2)对于斜率绝对值大于1的区域内在y方向取单位量;
斜率可以通过椭圆的标准方程中获得为K = - (ry_ry)__/(r__r_)_y;这里中点椭圆222222222。

第4讲 中点Bresanham算法

第4讲 中点Bresanham算法

15
0≤k≤1 0≤k≤1 0≤k≤1时Bresenham算法的算法步骤 算法步骤为: 算法步骤 1.输入直线的两端点P0(x0,y0)和P1(x1,y1). 2.计算初始值△x,△y,d=0.5-k,x=x0,y=y0; 3.绘制点(x,y).判断d的符号; 若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1-k; 否则(x,y)更新为(x+1,y),d更新为d-k. 4.当直线没有画完时,重复步骤3.否则结束. 参见程序brsham0.c 参见程序
判别式: 判别式
1≤k 1≤k
d = F ( xM , yM ) = F ( xi + 0.5, yi + 1) = yi + 1 k ( xi + 0.5) b
则有:
x x= x + 1
( d < 0) ( d ≥ 0)
Q P (x i +1,yi +1) u M
i
P(xi ,yi )
2010-7-27 信息科学与工程学院 23
2010-7-27 信息科学与工程学院 2
5.1.1 数值微分法 DDA法) 数值微分法(
直线的微分方程:设两端点为P(x0,y0), P(x1,y1)
dy y y1 y0 = = =k dx x x1 x0
DDA算法原理: DDA算法原理: 算法原理
由于直线的一阶导数是连续的,而且对于△x和△y 是成比例的,因此,可通过在当前位置(xi,yi )上分 别加上2个小增量ε△x和ε△y(ε为无穷小的正数)来 求出下一点的坐标(xi+1,yi+1) ,如图所示:
2010-7-27 信息科学与工程学院 16

中点bresenham算法斜率大于1例题

中点bresenham算法斜率大于1例题

随着计算机图形学的发展,Bresenham算法作为一种高效的直线扫描算法被广泛应用。

本文将结合中点Bresenham算法和斜率大于1的具体例题,深入探讨其原理及应用。

1. 中点Bresenham算法中点Bresenham算法是一种用于绘制直线的算法,其特点是高效、精确。

该算法通过在每个x处选择最接近直线的y坐标,从而实现了高效的直线绘制。

中点Bresenham算法的原理可用以下步骤描述:1)假设直线连接点A(x0, y0)和点B(x1, y1)。

2)计算直线斜率m = (y1-y0)/(x1-x0)。

3)设置初始值x=x0, y=y0。

4)计算决策参数P0 = 2*(y1-y0) - (x1-x0)。

5)循环执行以下步骤直至x达到x1:a) 如果P0<0,则选择点(x+1, y),即决策参数P0 = P0 + 2*(y1-y0)。

b) 如果P0>=0,则选择点(x+1, y+1),即决策参数P0 = P0 + 2*(y1-y0) - 2*(x1-x0)。

2. 斜率大于1的例题假设有一条直线连接点A(2, 5)和点B(7, 10),斜率m = (10-5)/(7-2) = 1。

我们可以通过中点Bresenham算法来绘制这条直线,具体步骤如下:1)设定初始值 x=2, y=5;2)计算初始的决策参数P0 = 2*(10-5) - (7-2) = 10;3)根据决策参数P0的值来确定下一个点的位置:a) 当P0<0时,选择点(3, 5),更新P0 = P0 + 10 = 20;b) 当P0>=0时,选择点(4, 6),更新P0 = P0 + 10 - 10 = 20;c) 重复上述步骤直至x=7。

3. 结论通过上述例题的分析,我们可以看出中点Bresenham算法在斜率大于1的情况下同样适用,并且能够高效地绘制直线。

其原理简单易懂,应用广泛,是计算机图形学领域的重要算法之一。

中点bresenham算法过程描述

中点bresenham算法过程描述

中点Bresenham算法是一种在计算机图形学中用于绘制直线的算法。

它是由Bresenham在1965年提出的,经过研究和改良后,成为一种非常高效的直线绘制算法。

1. 算法描述中点Bresenham算法的基本思想是利用线的对称性来进行计算,通过计算线上的各个像素点与理想直线的距离来确定下一个要绘制的像素点,从而高效地绘制直线。

2. 算法过程具体来说,中点Bresenham算法的计算过程如下:1) 首先确定直线的起点(x0, y0)和终点(x1, y1),并计算直线的斜率k = (y1 - y0) / (x1 - x0)。

2) 然后计算直线的斜率误差delta = |k| - 0.5。

3) 初始化绘制像素点的坐标(x, y),初始误差值为0。

4) 对于直线斜率绝对值小于1的情况:a) 如果斜率k大于0,则初始误差值为0.5,否则为-0.5。

b) 从x0到x1的范围内,依次计算每个像素点的y坐标,并根据误差值确定下一个像素点的位置,并更新误差值。

c) 如果误差值大于0,表示下一个像素点在直线的下边,否则在上边。

5) 对于直线斜率绝对值大于1的情况,可以通过将直线绘制区域进行旋转并交换x和y坐标来处理。

6) 最终绘制直线时,可以根据具体的应用场景选择存储像素点的方式,比如直接在屏幕上绘制,或者存储在像素数组中后再一次性绘制等。

3. 算法优势中点Bresenham算法相对于其他直线绘制算法的优势在于:它避免了复杂的浮点数计算,减少了计算量,提高了绘制的效率。

尤其在早期计算机硬件性能有限的情况下,该算法表现出了明显的优势,成为了广泛使用的直线绘制算法。

4. 算法应用中点Bresenham算法不仅仅局限于直线的绘制,它还可以应用于其他图形的绘制,比如圆、椭圆、矩形等。

在计算机图形学和图像处理领域,Bresenham算法及其改进版本被广泛应用于各种图形的绘制和处理中。

5. 算法总结中点Bresenham算法是一种非常经典且高效的直线绘制算法,它通过简单的整数运算和位操作实现了高效的直线绘制,成为了计算机图形学中不可或缺的重要工具之一。

《图形学》实验七:中点Bresenham算法画椭圆

《图形学》实验七:中点Bresenham算法画椭圆

《图形学》实验七:中点Bresenham算法画椭圆VC++6.0,OpenGL使⽤中点Bresenham算法画椭圆。

1 #include <gl/glut.h>23#define WIDTH 5004#define HEIGHT 5005#define OFFSET 15 //偏移量,偏移到原点6#define A 67#define B 589void Init() //其它初始化10 {11 glClearColor(1.0f,1.0f,1.0f,1.0f); //设置背景颜⾊,完全不透明12 glColor3f(1.0f,0.0f,0.0f); //设置画笔颜⾊1314 glMatrixMode(GL_PROJECTION);15 glLoadIdentity();16 gluOrtho2D(0.0, 30.0, 0.0, 30.0);17 glMatrixMode(GL_MODELVIEW);18 }1920void MidBresenhamEllipse(int a,int b) //中点Bresenham算法画椭圆21 {22int x,y;23float d1,d2;24 x = 0;y = b;25 d1=b*b+a*a*(-b+0.25);26 glPointSize(5); //设置画笔尺⼨2728 glBegin(GL_POINTS);29 glVertex2i(OFFSET+x,OFFSET+y);30 glVertex2i(OFFSET-x,OFFSET-y);31 glVertex2i(OFFSET-x,OFFSET+y);32 glVertex2i(OFFSET+x,OFFSET-y);33 glEnd();3435while(b*b*(x+1) < a*a*(y-0.5)){36if(d1<=0){37 d1+=b*b*(2*x+3);38 x++;39 }40else{41 d1+=b*b*(2*x+3)+a*a*(-2*y+2);42 x++;43 y--;44 }45 glBegin(GL_POINTS);46 glVertex2i(OFFSET+x,OFFSET+y);47 glVertex2i(OFFSET-x,OFFSET-y);48 glVertex2i(OFFSET-x,OFFSET+y);49 glVertex2i(OFFSET+x,OFFSET-y);50 glEnd();51 }//while上半部分52 d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;53while(y>0){54if(d2<=0){55 d2+=b*b*(2*x+2)+a*a*(-2*y+3);56 x++,y--;57 }58else{59 d2+=a*a*(-2*y+3);60 y--;61 }62 glBegin(GL_POINTS);63 glVertex2i(OFFSET+x,OFFSET+y);64 glVertex2i(OFFSET-x,OFFSET-y);65 glVertex2i(OFFSET-x,OFFSET+y);66 glVertex2i(OFFSET+x,OFFSET-y);67 glEnd();68 }69 }7071void Display()72 {73 glClear(GL_COLOR_BUFFER_BIT); //清空颜⾊堆栈7475 MidBresenhamEllipse(A,B); //画⼀个半径为8的椭圆7677 glFlush(); //清空缓冲区指令78 }7980int main(int argc,char** argv)81 {82 glutInit(&argc,argv);83 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //初始化显⽰模式84 glutInitWindowSize(WIDTH,HEIGHT); //初始化窗⼝⼤⼩85 glutInitWindowPosition(200,100); //初始化窗⼝出现位置86 glutCreateWindow("中点Bresenham画椭圆"); //初始化窗⼝标题8788 glutDisplayFunc(Display); //注册显⽰函数89 Init(); //其它初始化90 glutMainLoop(); //进⼊程序循环9192return0;93 }Freecode :。

椭圆的生成算法原理

椭圆的生成算法原理

椭圆的生成算法原理椭圆是数学中一个重要的几何图形,其形状类似于拉伸的圆,具有许多特殊的性质和应用。

椭圆的生成算法是指通过一系列步骤和公式来确定椭圆上各个点的坐标,即生成椭圆的过程。

下面将详细介绍椭圆的生成算法原理。

椭圆的生成算法主要有两种,一种是解析生成算法,另一种是数值生成算法。

1. 解析生成算法:解析生成算法是通过椭圆的几何性质以及数学公式来确定椭圆上各个点的坐标。

椭圆的数学定义是平面上到两个定点F1和F2的距离之和恒定的点的集合,这个距离之和被称为椭圆的焦距。

椭圆的生成算法可以通过以下步骤来实现:(1)确定椭圆的中心点坐标:椭圆的中心点坐标是椭圆坐标系的原点,可以通过给定的椭圆中心点位置来确定。

(2)确定椭圆的长轴和短轴长度:椭圆的长轴和短轴是确定椭圆形状的关键参数,可以通过给定的椭圆长轴长度和短轴长度来确定。

(3)确定椭圆的旋转角度:椭圆可以绕着中心点旋转一定角度,旋转角度可以通过给定的旋转角来确定。

(4)根据椭圆的数学公式确定椭圆上各个点的坐标:椭圆的数学公式为:x = a * cosθ,y = b * sinθ,其中a和b分别是椭圆的长轴和短轴长度,θ是点P在椭圆上的极角。

通过以上步骤,椭圆的生成算法能够确定椭圆上任意给定角度的点的坐标。

2. 数值生成算法:数值生成算法是通过数值计算的方法来确定椭圆上各个点的坐标。

常用的数值生成算法有Bresenham算法和中点画圆法。

(1)Bresenham算法:Bresenham算法是一种通过离散化的方法来绘制椭圆的生成算法。

该算法通过遍历椭圆的象限来确定椭圆上各个点的坐标,并在每个象限内使用Bresenham画线算法来绘制曲线。

(2)中点画圆法:中点画圆法是一种通过迭代计算的方法来绘制椭圆的生成算法。

该算法通过以椭圆的中心点为起点,按照逆时针方向遍历椭圆的一个象限,根据一个决策参数来确定椭圆上各个点的坐标。

这两种数值生成算法能够准确地绘制椭圆,适用于计算机图形学等领域。

Bresenham算法画椭圆和斜椭圆

Bresenham算法画椭圆和斜椭圆

Bresenham算法画椭圆和斜椭圆CG课程的第⼀次作业,⼤四才开始学CG也算是很特别【然后就迟交了⼀天】。

Bresenham算法⽤于把连续曲线投影到平⾯像素中,思想是只要能判断x和y哪个增量更⼤,就可以按x+1(或y+1)之后y(或x)是否+1来画下⼀个像素。

判断是⽤x还是y的标准是斜率⼤于1还是⼩于1,在这个基础上⽹上能够搜到的椭圆画法做了⼀些优化,1.只⽤画⼀个象限内的曲线,另外三个象限直接对称过去;2.以x增量更⼤(斜率⼩于1)的情况为例,判断y是否+1的⽅法不是把y和y+1都算⼀遍,⽽是⽤y+0.5在圆内还是圆外判断;3.再进⼀步,每次都带⼊⽅程去算d=F(x,y+0.5)也很慢,可以考虑⽤算增量代替。

这部分我觉得讲得⽐较好的是。

⽐较⿇烦的是斜椭圆的情况,⾸先,按照前⾯的思路,要重新把公式推⼀遍,斜椭圆的公式是在椭圆的基础上把x和y⽤旋转变换替换,你博能不能插⼊公式啊,试试:椭圆公式:x2 a2+y2b2=1旋转变换:cosβ−sinβsinβcosβxy=x cosβ−y sinβx sinβ+y cosβ代⼊得到斜椭圆公式:(x cosβ−y sinβ)2a2+(x sinβ+y cosβ)2b2=1在这⾥推荐Mathpix Snipping Tool,远离⼿打latex从我做起【不是】得到曲线函数之后,按照算法核⼼思想,⾸先要判断的是切线斜率,在这⾥要⽤到隐函数求导:dydx=−F x F y其中:F(x,y)=(x cosβ−y sinβ)2a2+(x sinβ+y cosβ)2b2−1为了⽅便编程,我去掉了上⾯对椭圆曲线做的三个优化,仅考虑最简单的Bresenham算法,那么公式的推导就可以到此为⽌了。

对于优化1,在斜椭圆本来就不成⽴,斜椭圆不再有四个象限的对称性质,只画第⼀象限不能完成曲线;但是有中⼼对称,所以我只画了第⼀象限和第四象限,另外两个象限对称处理。

对于优化2,最⼤的问题是斜椭圆在同⼀象限内的凹凸性不再保持不变,⽽F(x,y+0.5)在圆外代表我们该取y还是y+1其实是和凹凸性有关的,画个图应该很好理解。

bresenham中点画圆原理介绍

bresenham中点画圆原理介绍

1.中点Bresenham 算法的原理圆心在原点、半径为R 的圆方程的隐函数表达式为:圆将平面划分成三个区域:对于圆上的点,F(x ,y)=0;对于圆外的点,F (x ,y )>0;对于圆内的点,F (x ,y )<0。

事实上,考虑到圆在第一象限内的对称性,本算法可以进一步简化。

用四条对称轴x =0,y =0, x =y,x =-y 把圆分成8等份。

只要绘制出第一象限内的1/8圆弧,根据对称性就可绘制出整圆,这称为八分法画圆算法。

假定第一象限内的任意点为P (x,y ),可以顺时针确定另外7个点:P (y ,x ),P (y ,-x ),P (x,- y ),P (-x ,-y ),P (-y ,-x ),P (-y ,x ),P (-x ,y )。

2.构造中点偏差判别式从P (xi ,yi )开始,为了进行下一像素点的选取,需将Pu 和Pd 的中点M (x i+1,y i-0.5)代入隐函数,构造中点偏差判别式:⑴当d<0时,下一步的中点坐标为:M (xi +2,yi -0.5)。

下一步中点偏差判别式为:⑵当d ≥0时,下一步的中点坐标为:M (xi +2,yi -1.5)。

),(222=-+=R y x y xF )5.0,1(),(-+==i i M M y x F y x F d ⎩⎨⎧≥<=+)0( 1-)0(1d y d y y i i i 2221)5.0()2()5.0,2(R y x y x F d i i i i i --++=-+=+3232)5.0()1(222++=++--++=i i i i i x d x R yx2221)5.1()2()5.1,2(R y x y x F d i i i i i --++=-+=+。

圆锥曲线算法

圆锥曲线算法

圆锥曲线算法
圆锥曲线是指在平面上生成的一类特殊曲线,包括椭圆、双曲线和抛物线。

下面是关于圆锥曲线的一些常见算法:
1. 椭圆算法:
- 中点椭圆算法(Midpoint Ellipse Algorithm):该算法通过逐步逼近椭圆曲线的各个点,并利用对称性进行计算,实现了高效的椭圆绘制。

- Bresenham椭圆算法:该算法基于Bresenham直线算法,通过分析椭圆的象限对称性,以及对象限内各点的落点判定来绘制椭圆。

2. 双曲线算法:
- 中点双曲线算法(Midpoint Hyperbola Algorithm):该算法类似于中点椭圆算法,通过逐步逼近双曲线曲线的各个点,并利用对称性进行计算,实现了高效的双曲线绘制。

3. 抛物线算法:
- 中点抛物线算法(Midpoint Parabola Algorithm):该算法通过逐步逼近抛物线曲线的各个点,并利用对称性进行计算,实现了高效的抛物线绘制。

这些算法能够在计算机上绘制出高效和精确的圆锥曲线。

具体实现时,您可以根据需要选择适合的算法,并基于C++或其他编程语言进行实现。

对于特定的圆锥曲线问题,还可以考虑使用数学库或图形库提供的相应函数或类来绘制和处理圆锥曲线。

Bresenham算法画圆

Bresenham算法画圆

Bresenham算法画圆bresenham画圆算法bresenham画圆算法中点画圆算法在⼀个⽅向上取单位间隔,在另⼀个⽅向的取值由两种可能取值的中点离圆的远近⽽定。

实际处理中,⽤决策变量的符号来确定象素点的选择,因此算法效率较⾼。

⼀、中点画圆算法描述设要显⽰圆的圆⼼在原点(0,0),半径为R,起点在(0,R)处,终点在(,)处,顺时针⽣成⼋分之⼀圆,利⽤对称性扫描转换全部圆。

为了应⽤中点画圆法,我们定义⼀个圆函数F(x,y)=x2+y2-R2 (2-19)任何点(x,y)的相对位置可由圆函数的符号来检测:F(x,y) <0点(x,y)位于数学圆内=0点(x,y)位于数学圆上>0点(x,y)位于数学圆外(2-20)如下图所⽰,图中有两条圆弧A和B,假定当前取点为Pi(xi,yi),如果顺时针⽣成圆,那么下⼀点只能取正右⽅的点E(xi+1,yi)或右下⽅的点SE(xi+1,yi-1)两者之⼀。

中点画线算法假设M是E和SE的中点,即,则:1、当F(M)<0时,M在圆内(圆弧A),这说明点E距离圆更近,应取点E作为下⼀象素点;2、当F(M)>0时,M在圆外(圆弧B),表明SE点离圆更近,应取SE点;3、当F(M)=0时,在E点与SE点之中随便取⼀个即可,我们约定取SE点。

⼆、中点画圆算法思想因此,我们⽤中点M的圆函数作为决策变量d i,同时⽤增量法来迭代计算下⼀个中点M的决策变量d i+1。

(2-21)下⾯分两种情况来讨论在迭代计算中决策变量d i+1的推导。

1、见图(a),若d i <0,则选择E点,接着下⼀个中点就是,这时新的决策变量为:(2-22)(a)(di<0) 中点画线算法式(2-22)减去(2-21)得:d i+1=d i+2x i+3(2-23)2、见图(b),若di≥0,则选择SE点,接着下⼀个中点就是,这时新的决策变量为:(2-24)(b)(d i ≥0) 中点画线算法式(2-24)减去(2-21)得:d i+1=d i+2(x i-y i)+5(2-25)我们利⽤递推迭代计算这⼋分之⼀圆弧上的每个点,每次迭代需要两步处理:(1)⽤前⼀次迭代算出的决策变量的符号来决定本次选择的点。

Bresenham椭圆算法

Bresenham椭圆算法

GIS专业实验报告(计算机图形学)实验3 使用Bresenham画椭圆算法,绘制一个椭圆一.实验目的及要求根据Bresenham画椭圆算法,掌握绘制椭圆的程序设计方法。

在绘制时应利用椭圆的对称性。

注意,不能使用语言库中的画圆函数。

二.理论基础1.Bresenham椭圆算法:中点Bresenham椭圆绘制算法的基本原理与中点Bresenham画圆算法类似,也是尽可能的迫近椭圆(多边形迫近法),推导出圆弧的增量算法的表达式,找到最接近椭圆圆弧的像素点。

三.算法设计与分析算法步骤:(1) 输入椭圆的长半轴a和短半轴b。

(2) 计算初始值d = b*b + a * a * (-b + 0.25), x = 0, y = b。

(3) 绘制点 (x, y)及其在四分象限上的另外3个对称点。

(4) 判断d的符号。

若d <= 0,则先将d更新为d + b * b * (2 * x + 3),再将 (x,y)更新为(x+1, y);否则先将d更新为d + b * b * (2 * x + 3) + a * a (-2 * y +2),再将(x, y)更新为(x+1, y-1)。

(5) 当b*b * (x+1) < a * a * (y - 0.5)时,重复步骤(3)和(4),否则转到步骤(6)。

(6) 用上半部分计算的最后点(x, y)来计算下半部分中d的初值: d = b * b * (x +0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b。

(7) 绘制点(x, y)及其在四分象限上的另外3个对称点。

(8) 判断d的符号。

若d <= 0,则先将d更新为d + b * b * (2 * xi + 2) + a * a* (-2 * yi + 3), 再将(x, y)更新为(x+1, y-1);否则先将d更新为d + a * a * (-2 * yi + 3),再将(x, y)更新为(x, y-1)。

计算机图形学--Bresenham完整算法-画直线、椭圆和圆

计算机图形学--Bresenham完整算法-画直线、椭圆和圆

#include<windows.h>#include<gl/glut.h>#include"stdio.h"int m_PointNumber = 0; //动画时绘制点的数目int m_DrawMode = 1; //绘制模式 1 DDA算法画直线// 2 中点Bresenham算法画直线// 3 改进Bresenham算法画直线// 4 八分法绘制圆// 5 四分法绘制椭圆//绘制坐标线void DrawCordinateLine(void){int i = -250 ;//坐标线为黑色glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=-250;i<=250;i=i+10){glVertex2f((float)(i), -250.0f);glVertex2f((float)(i), 250.0f);glVertex2f(-250.0f, (float)(i));glVertex2f(250.0f, (float)(i));}glEnd();}//绘制一个点,这里用一个正方形表示一个点void putpixel(GLsizei x, GLsizei y){glRectf(10*x,10*y,10*x+10,10*y+10);}/////////////////////////////////////////////////////////////////////DDA画线算法 //// //// //// /////////////////////////////////////////////////////////////////////void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {//设置颜色glColor3f(1.0f,0.0f,0.0f);//对画线动画进行控制if(num == 1)printf("DDA画线算法:各点坐标\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,epsl,k;GLfloat x,y,xIncre,yIncre;dx = x1-x0;dy = y1-y0;x = x0;y = y0;if(abs(dx) > abs(dy)) epsl = abs(dx);else epsl = abs(dy);xIncre = (float)dx / epsl ;yIncre = (float)dy / epsl ;for(k = 0; k<=epsl; k++){putpixel((int)(x+0.5), (int)(y+0.5));if (k>=num-1) {printf("x=%f , y=%f,取整后 x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));break;}x += xIncre;y += yIncre;if(x >= 25 || y >= 25) break;}}/////////////////////////////////////////////////////////////////////中点Bresenham算法画直线(0<=k<=1) //// //// //// /////////////////////////////////////////////////////////////////////void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("中点Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;GLfloat UpIncre,DownIncre,x,y,d,k,dx,dy;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}if(k>1){d=dy-2*dx;UpIncre=2*dy-2*dx;DownIncre=-2*dx;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}if(k<0&&k>=-1){d=dx-2*dy;UpIncre=-2*dy;DownIncre=-2*dx-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d>0){y--;d+=DownIncre;}else d+=UpIncre;}}if(k<-1){d=-dy-2*dx;UpIncre=-2*dx-2*dy;DownIncre=-2*dx;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}}/////////////////////////////////////////////////////////////////////改进的Bresenham算法画直线(0<=k<=1) //// //// x1,y1 终点坐标 //// /////////////////////////////////////////////////////////////////////void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei x,y,dx,dy,e,k;if(num == 1)printf("改进的Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}if(k>1){e=-dy;x=x0;y=y0;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;e=e+2*dx;if(e>0){x++;e=e-2*dy;}}}if(k<0&&k>=-1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e<0){y--;e=e+2*dx;}}}if(k<-1){e=-dy;x=x0;y=y0;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;e=e-2*dx;if(e<0){x++;e=e-2*dy;}}}}///////////////////////////////////////////////////////////Bresenham算法画圆 //// //// //// ///////////////////////////////////////////////////////////void CirclePoint(GLsizei x,GLsizei y){ putpixel(x,y);putpixel(x,-y);putpixel(y,-x);putpixel(-y,-x);putpixel(-x,-y);putpixel(-x,y);putpixel(-y,x);putpixel(y,x);}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei R, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei d;x=0;y=R;d=1-R;if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");else if(num==0)return;while(x<=y){CirclePoint(x,y);if (x>=num-1) {printf("x=%d,y=%d,d=%d\n", x, y,d);break;}if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}void Bresenham2Circle(GLsizei a,GLsizei b,GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num==1)printf("Bresenham算法画椭圆:各点坐标及判别式的值\n");else if(num==0)return;GLsizei x,y;float d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.5);putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);while(b*b*(x+1)<a*a*(y-0.5)){if (x>=num-1) {printf("x=%d,y=%d,d1=%d\n", x, y,d1);break;}if(d1<=0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}//while上半部分d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while(y>0){if (x>=num-1) {printf("x=%d,y=%d,d2=%d\n", x, y,d2);break;}if(d2<=0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}}//初始化窗口void Initial(void){// 设置窗口颜色为蓝色glClearColor(0.0f, 0.0f, 1.0f, 1.0f);}// 窗口大小改变时调用的登记函数void ChangeSize(GLsizei w, GLsizei h){if(h == 0) h = 1;// 设置视区尺寸glViewport(0,0, w, h);// 重置坐标系统glMatrixMode(GL_PROJECTION);glLoadIdentity();// 建立修剪空间的范围if (w <= h)glOrtho (-250.0f, 250.0f, -250.0f, 250.0f*h/w, 1.0, -1.0);elseglOrtho (-250.0f, 250.0f*w/h, -250.0f, 250.0f, 1.0, -1.0);}// 在窗口中绘制图形void ReDraw(void){//用当前背景色填充窗口glClear(GL_COLOR_BUFFER_BIT);//画出坐标线DrawCordinateLine();switch(m_DrawMode){case 1:DDACreateLine(0,0,20,15,m_PointNumber);break;case 2:BresenhamLine(0,0,-20,15,m_PointNumber);break;case 3:Bresenham2Line(1,1,8,6,m_PointNumber);break;case 4:BresenhamCircle(0,0,20,m_PointNumber);break;case 5:Bresenham2Circle(10,8,m_PointNumber);default:break;}glFlush();}//设置时间回调函数void TimerFunc(int value){if(m_PointNumber == 0)value = 1;m_PointNumber = value;glutPostRedisplay();glutTimerFunc(500, TimerFunc, value+1);}//设置键盘回调函数void Keyboard(unsigned char key, int x, int y) {if (key == '1') m_DrawMode = 1;if (key == '2') m_DrawMode = 2;if (key == '3') m_DrawMode = 3;if (key == '4') m_DrawMode = 4;if (key == '5') m_DrawMode = 5;m_PointNumber = 0;glutPostRedisplay();}//void main(void)int main(int argc, char* argv[]){glutInit(&argc, argv);//初始化GLUT库OpenGL窗口的显示模式glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600,600);glutInitWindowPosition(100,100);glutCreateWindow("基本图元绘制程序);glutDisplayFunc(ReDraw);glutReshapeFunc(ChangeSize);glutKeyboardFunc(Keyboard);//键盘响应回调函数glutTimerFunc(500, TimerFunc, 1);// 窗口初始化Initial();glutMainLoop(); //启动事件处理循环return 0;}。

计算机图形学-画椭圆和圆

计算机图形学-画椭圆和圆
y--;
}
x++;
glVertex2i(x +xc, y +yc);
glVertex2i(y +xc, x +yc);
glVertex2i(y +xc, -x +yc);
glVertex2i(x +xc, -y +yc);
glVertex2i(-x +xc, -y +yc);
glVertex2i(-y +xc, -x +yc);
绘图过程如下:
.输入直线的两端点P0(X0,Y0)和P1(X1,Y1)。
.计算初始值△x, △y,d=△x-2△y,x=X0,y=Y0.
.绘制点(x,y)。判断d的符号,若d<0,则(x,y)更新为(x+1,y+1),d更新为d+2△x-2△y;否则(x,y)更新为(x+1,y),d更新为△y。
.当直线没有画完时,重复步骤 ,否则结束。
intx = 0;
inty =b;
Ellipsepot(x0,y0, x, y);
// 1
while(sqb*(x + 1) < sqa*(y - 0.5))
{
if(d < 0)
{
d += sqb*(2 * x + 3);
}
else
{
d += (sqb*(2 * x + 3) + sqa*((-2)*y + 2));
glVertex2i(198,2);
glEnd();
glFlush(); //清空OpenGL命令缓冲区,执行OpenGL程序

中点bresenham算法的基本原理与递推公式

中点bresenham算法的基本原理与递推公式

中点Bresenham算法是一种用于绘制直线的光栅化算法,它可以在计算机图形学中高效地绘制直线,尤其适用于嵌入式系统和低性能设备。

本文将介绍中点Bresenham算法的基本原理和递推公式。

一、中点Bresenham算法的基本原理1.1 数值方式直线的差值算法在了解中点Bresenham算法之前,我们需要先了解数值方式直线的差值算法。

通过计算两个端点的坐标差值,可以得到直线的斜率和步长,从而在光栅化的像素网格上绘制直线。

然而,这种算法需要进行浮点数运算,对于嵌入式系统和低性能设备来说,性能较差。

1.2 中点Bresenham算法的优势中点Bresenham算法通过整数运算和递推公式来高效地绘制直线,避免了浮点数运算的开销,因此在嵌入式系统和低性能设备上具有很高的应用价值。

它利用了直线的对称性和整数坐标的特点,通过逐个像素的递推计算来实现直线的绘制。

1.3 算法的基本思想中点Bresenham算法的基本思想是从直线的起点到终点,在每一步选择最接近直线的像素作为下一个像素,从而逐步绘制整条直线。

通过比较像素的位置和理想直线的位置关系,选择最接近直线的像素进行绘制,从而得到了中点Bresenham算法的递推过程。

二、中点Bresenham算法的递推公式2.1 直线斜率的计算我们需要计算直线的斜率m。

对于给定的两个端点P1(x1, y1)和P2(x2, y2),直线的斜率可以通过以下公式计算得到:m = (y2 - y1) / (x2 - x1)2.2 中点Bresenham算法的关键递推公式中点Bresenham算法通过比较像素的位置和理想直线的位置关系,选择最接近直线的像素进行绘制。

其关键递推公式如下:对于斜率0 ≤ m ≤ 1的直线:d = 2 * (y - y0) - (x - x0)若d < 0,则选择(x, y)为下一个像素,d = d + 2 * (y1 - y0)若d ≥ 0,则选择(x, y)为下一个像素,d = d + 2 * (y1 - y0) - 2 * (x1 - x0)对于斜率m > 1的直线:d = 2 * (x - x0) - (y - y0)若d < 0,则选择(x, y)为下一个像素,d = d + 2 * (x1 - x0)若d ≥ 0,则选择(x, y)为下一个像素,d = d + 2 * (x1 - x0) - 2 * (y1 - y0)2.3 递推过程通过以上递推公式,我们可以在每一步选择最接近直线的像素进行绘制,从而逐步绘制整条直线。

§3.3椭圆的生成——中点算法

§3.3椭圆的生成——中点算法

§3.3椭圆的生成——中点算法是椭圆的特例,所以可以直接扩展Bresenham 的画圆光栅算法。

但是,Van Aken 指出Bresenham 画圆算法扩展到椭圆不能保证实际椭圆与所选像素之间的线性误差最小。

他给出了一种用于椭圆的技术,称为中点算法。

中心在原点、轴对称椭圆方程为:或f(x,y)=b 2x 2+a 2y 2-a 2b 2=0其中a,b 分别是半长轴和半短轴,该椭圆与x 轴相交于x=a ,与y 轴相交于y=b 。

这里只考虑椭圆在第一象限的部分,其它象限的部分可作相应的对称变换而得。

中心不在原点的椭圆可通过平移得到得到。

在这段椭圆弧上,y 随x 的增加而减小,即y 是x 的单调递减函数。

在这段圆弧上,以切线斜率为-1的点(即法向量的两个分量相等的点)将其分为上下两部分。

如果以点x=a ,y=0为起点按逆时针方向生成椭圆,当前像素为S(x i ,y i ),那么在区域1,下一个像素只有两种可能,即V(x i ,y i +1) 、D(x i -1,y i +1)。

它们的中点为M(x i -0.5,y i +1)。

圆12222=+by a xY如果椭圆通过M 的右部,则取像素V ,如果通过M 的左侧,则选择像素D 。

在区域2,下一个像素只有两种可能,即H(x i -1,y i ) 、D(x i -1,y i +1)。

它们的中点为M(x i -1,y i +0.5)。

如果椭圆通过M 的上部,则取像素D ,如果通过M 的下部,则选择像素H 。

而最大线性误差为:-1/2≤e≤1/2那么,判断椭圆通过中点M 的左右或上下的方法是什么呢? 将决策变量d i 定义为f(x,y)在中点处值的两倍。

首先考察区域1:如果椭圆通过中点M ,则d 1i =0,但是椭圆很可能要通过中点M 的右部或左部(x i-0.5+e1,y i +1)。

因为该点在椭圆上,因此有:(X i ,y i )(X i ,y i +1)(X i ,y i )22222222222212)242()2122(])1()5.0([2)1,5.0(2b a y y a x x b b a y a x b y x f d i i i i i i i i i -++++-=-++-=+-=01)5.0(12)1,5.0(0)1()15.0()1,15.0(222222222=+-++-==-+++-=++-e b x e b y x f b a y a e x b y e x f i i i i i i i将d1i/2=f(x i-0.5,y i+1)代入,则:d1i=-4b2e1(x i-0.5)-2b2e12=-2b2e1[(2x i-1)+e1]注意到d1i的符号与e1的符号正好相反。

中点bresenham算法负斜率

中点bresenham算法负斜率

一、概述Bresenham算法是一种用于计算直线、圆和椭圆等图形的算法,是由Jack Elton Bresenham在1962年提出的。

在计算机图形学领域,Bresenham算法广泛应用于直线绘制,它可以高效地计算出直线上的像素点,是图形绘制中不可缺少的重要算法之一。

二、Bresenham算法原理Bresenham算法通过计算像素点的坐标,来实现直线绘制。

对于一条从点P0(x0, y0)到点P1(x1, y1)的直线,我们需要找出直线经过的所有像素点,Bresenham算法便是通过斜率的计算和递推关系,来确定每个像素点的位置并进行绘制。

三、Bresenham算法计算流程1. 根据P0和P1计算出直线的斜率k。

2. 根据斜率k的值,分为正斜率和负斜率两种情况进行处理。

3. 在具体实现中,我们可以通过判断斜率k的绝对值来确定直线画法的不同情况,细分为0<k<1、k>1、-1<k<0和k<-1四个基本情况,以简化直线绘制的过程。

四、Bresenham算法负斜率情况分析对于Bresenham算法而言,处理负斜率直线是一个非常重要且复杂的情况。

当直线的斜率k小于0时,我们需要根据不同的取值范围采用不同的算法流程来确定像素点的位置并进行绘制。

五、Bresenham算法负斜率实现1. 我们需要对直线的起点和终点进行判断,确定起点和终点的坐标值。

2. 根据斜率k的负值来分情况处理。

当-1<k<0时,我们需要沿着主方向y自增,次方向x自减;当k<-1时,则需要沿着主方向x自减,次方向y自增。

3. 确定像素点的位置后,进行像素绘制。

六、Bresenham算法负斜率实例演示以具体数值为例,对一条直线上的像素点位置进行计算和绘制演示,以便更好地理解Bresenham算法在处理负斜率直线时的实现流程和细节。

七、Bresenham算法负斜率应用Bresenham算法在计算机图形学中的应用非常广泛,尤其是在直线绘制和图形显示领域。

写出椭圆bresenham光栅化方法

写出椭圆bresenham光栅化方法

写出椭圆bresenham光栅化方法Bresenham的椭圆光栅化算法是一种在计算机图形学中用于生成椭圆的方法。

这种方法基于Bresenham的线算法,通过在离散的像素网格上模拟连续的几何形状。

以下是Bresenham的椭圆光栅化方法的步骤:
1. 初始化:首先,我们需要知道椭圆的中心点(h, k),长半轴 a 和短半轴b。

然后,我们需要初始化两个变量:p 为 1,q 为a² - b²。

2. 确定步长:根据 p 和 q 的值,我们可以决定在 x 方向(或 y 方向)上是否前进一个像素。

如果p ≥ 0,那么我们在 x 方向上前进,否则我们在 y 方向上前进。

然后,我们更新 p 和 q 的值:
如果我们在 x 方向上前进,那么 p = p - q
如果我们在 y 方向上前进,那么 q = q - p
3. 绘制椭圆:根据上述步骤,我们可以在椭圆上逐点绘制像素。

在每个点上,我们都根据需要更新 p 和 q 的值。

4. 结束条件:当我们在椭圆的一个方向上到达边界时,我们停止绘制。

这个算法的关键在于利用了整数运算和比较运算,使得在每个像素点上只需要进行一次判断,大大减少了计算的复杂性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录一、设计题目 (2)二、设计要求 (2)三、设计方案 (2)四、程序流程图 (6)五、程序清单 (7)六、程序运行结果分析 (15)七、系统不足及改进方案 (15)八、设计总结 (16)一、设计题目:椭圆中点Bresenham算法二、设计要求:1、要求有两种输入方式:(1)输入椭圆的长短轴来生成椭圆;(2)根据输入点来生成椭圆并输出椭圆的长短轴;2、椭圆的颜色为红色;三、设计方案:1、椭圆对称性质:椭圆分别关于X轴、Y轴对称。

因此在计算椭圆生成的时候,只需要计算1/4个椭圆,经过对称原理就可以实现其他3/4个椭圆的生成了,即:计算出目标点(x,y)的坐标,必然存在(x,-y)、(-x,y)(-x,-y)。

此方案中采用计算第一象限中椭圆的生成,即:计算x=0到y=0的1/4的椭圆。

先通过平移的方法将假设椭圆中心在坐标原点,然后计算,最后再平移到真实中心位置。

2、对于第一象限的椭圆,斜率k=-(b*b)*x/ (a*a)*y ,当x<y时,斜率k的绝对值小于1,计算时在x方向上取单位量;当x>y时,斜率k的绝对值大于1,计算时在y方向上取单位量。

记:x<y的区域为第一区域,x>y的区域为第二区域。

3、输入方式一:输入椭圆的长短轴来生成椭圆。

已知:长短半轴分别为a、b,计算的初始位置为(0,b)。

令d=F(M)=F(P x+1,P y-0.5)=b*b+a*a*(b-0.5)*(b-0.5)-a*a*b*b当P x=0、P y=b时,d的初始值为:d= b*b-a*a*b+1/4a*a○1d>=0时,应取P2作为下一个像素点,则其正右方的点的坐标为(P x+2,P y-1),右下方的点的坐标为(P x+2,P y-2),中点坐标为(P x+2,P y-1.5)。

此时,d=F(M)=F(P x+2,P y-1.5)=d+b*b*(2*P x+3)-2a*a*(P y-1)○2d<0时,应取P1作为下一个像素点,则其正右方的点的坐标为(P x +2,P y ),右下方的点的坐标为(P x +2,P y -1),中点坐标为(P x +2,P y-0.5)。

此时,d=F (M )=F (P x +2,P y -0.5)=d+2* b*b* P x +3* b*b(2)对于第二区域,如图2所示,P 点坐标为(P x ,P y ),P1(P x , P y -1)为P 点正下方的点、P2(P x +1, P y -1)为P 点右下方的点,M (P x +0.5,P y -1)为P1、P2的中点。

令d=F (M )=F (P x +0.5,P y -1)=b*b*(P x +0.5)*(P x +0.5)+a*a*(P y -1)*(P y -1)-a*a*b*b 设P 坐标的初始值为P x =0x ,P y =y ,x =yd 的初始值为:图4 输入方式二流程图五、程序清单// zhongdiansuanfa.cpp : Defines the entry point for the console application.#include "stdafx.h"#include <stdlib.h>#include <vector>#include <GL/glut.h>#include <math.h>int a;int b;/*定义长短半轴分别为a、b*/void GetValue(){int input=0;int x1,x2,y1,y2;printf("请输入中点算法产生的方式:\n");printf("1.输入椭圆长短半径\n");printf("2.输入椭圆坐标\n");/*输出两种输入方式*/scanf("%d",&input);if(input==1){printf("请输入a的值:\n");scanf("%d",&a);printf("请输入b的值:\n");scanf("%d",&b);}if(input==2){printf("请输入第一个坐标的值:\n");scanf("%d,%d",&x1,&y1);printf("请输入第二个坐标的值:\n");scanf("%d,%d",&x2,&y2);a=sqrt ((y1*y1*x2*x2-x1*x1*y2*y2)/(y1*y1-y2*y2));b=sqrt ((x1*x1*y2*y2-x2*x2*y1*y1)/(x1*x1-x2*x2)); /*根据输入的两个坐标计算椭圆长短半轴a、b的值*/printf("a=%d",a);printf("b=%d",b);/*输出长短半轴a、b的值*/}}void PointsEllipse(int x,int y){glColor3f (1.0f, 0.0f, 0.0f);/*生成的椭圆的颜色为红色*/glPointSize(1);glBegin (GL_POINTS);glVertex2i(x+200,y+200);glVertex2i(-x+200,y+200);glVertex2i(x+200,-y+200);glVertex2i(-x+200,-y+200);/*根据对称原理求出椭圆上各个点的坐标*/ glEnd ();}void myDisplay(){glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0f, 0.0f, 0.0f);glBegin (GL_POINTS);//int a=200,b=100;float x,y,d1,d2;x=0;y=b;/*第一区域的起始坐标*/d1=b*b+a*a*(-b+0.25);PointsEllipse(x,y);/*计算第一区域椭圆上各个点的坐标*/while(b*b*(x+1)<a*a*(y-0.5)){if (d1<0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}PointsEllipse(x,y);}/*计算第二区域椭圆上各个点的坐标*/d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b; /*第二区域的起始点处的d值*/while(y>0){if (d2<0){d2+=2*b*b*(x+1)-a*a*(2*y-3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}PointsEllipse(x,y);}glEnd ();glFlush();/*保证前面的OpenGL命令立即执行*/ }void Init(){GetValue();glClearColor(0.0, 0.0, 0.0, 0.0); /*定义清空颜色设计为黑色*/glShadeModel(GL_FLAT);}void Reshape(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); }int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);/*定义窗口在屏幕中的位置*/glutInitWindowSize(600, 600);/*定义窗口的大小*/glutCreateWindow("zhongdiansuanfa!");/*根据前述设置的信息创建窗口*/Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMainLoop();return 0;}六、程序运行结果分析运行该程序,窗口中显示:请输入中点算法产生的方式:1、输入椭圆长短半径。

2、输入椭圆坐标。

输入1,并单击回车,显示请输入a的值,输入a的值,并单击回车,将显示请输入b的值,输入b的值,并单击回车,屏幕上将显示一个以a、b为长短半轴的红色椭圆;输入2,并单击回车,将显示请输入第一个坐标的值,输入第一个坐标的值,并单击回车,将显示请输入第二个坐标的值,输入第二个坐标的值,并单击回车,屏幕上将显示一个以原点为中心,经过两个坐标的红色椭圆。

七、系统不足及改进方案该算法生成的椭圆以原点为中心,如果要想实现椭圆的中心可放在任何位置,则在上述算法中通过平移的方法将假设圆心在坐标原点,然后计算,最后再平移到真实的中心位置。

假设椭圆的中心坐标为(x-center ,y-center ),则()1''y x = ()1y x⎪⎪⎪⎭⎫ ⎝⎛--1010001center y center x 其中,()1''y x 为平移后的齐次坐标,()1y x 为平移前的齐次坐标,⎪⎪⎪⎭⎫ ⎝⎛--1010001center y center x 为平移向量。

八、设计总结回顾起此次计算机图形学课程设计,我仍感慨颇多,做这次课程设计之前我还自认为图形学这门课我学的还不错,但是当做设计时才发现原来还有这么多东西没有弄懂。

做完设计之后,感觉自己学到了很多很多的东西,同时不仅巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。

通过这次课程设计使我懂得了理论与实际相结合是重要性,只有理论知识没有实践,一切都等于虚设,相当于纸上谈兵。

只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能提高自己的实际动手能力和独立思考的能力。

在设计过程中遇到的问题,可以说得是困难重重,在老师同学的帮助下最终成功完成了这次设计。

通过这次课程设计之后,不仅把以前所学过的知识重新温故了一遍,而且又从中学到了很多知识。

总的来说,这次设计的还是比较成功的,在设计中遇到了很多问题,最后在老师的辛勤的指导下,终于游逆而解,有点小小的成就感,觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更加清楚的认识。

相关文档
最新文档