这里不仔细讲原理,只是把我写的算法发出来,跟大家分享下,如果有错误的话,还请大家告诉我,如果写的不好,也请指出来,一起讨论进步。

算法步骤:

(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)。

(9) 当y >= 0, 重复步骤(7)和(8),否则结束。

下面是算法:

#include <GL/freeglut.h>
void init (void)
{
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
} void drawEllipse (int a, int b, int xLoc, int yLoc)
{
glPushMatrix ();
int x, y;
float d1, d2, aa, bb;
aa = a * a;
bb = b * b;
d1 = bb + aa * (-b + 0.25);
glTranslatef ((GLfloat) xLoc, (GLfloat) yLoc, 0.0f);
x = 0;
y = b;
glBegin (GL_POINTS);
glVertex2i ( x, y);
glVertex2i (-x, y);
glVertex2i (-x, -y);
glVertex2i ( x, -y);
while (bb * (x + 1) < aa * (y - 0.5))
{
if (d1 <= -0.000001)
{
d1 += bb * ((x << 1) + 3); }
else
{
d1 += bb * ((x << 1) + 3) + aa * (2 - (y << 1));
-- y;
}
++ x;
glVertex2i ( x, y);
glVertex2i (-x, y);
glVertex2i (-x, -y);
glVertex2i ( x, -y);
}
d2 = bb * (0.25 * x) + aa * (1 - (y << 1));
while (y > 0)
{
if (d2 <= -0.000001)
{
++ x;
d2 += bb * ((x + 1) << 1) + aa * (3 - (y << 1));
}
else
{
d2 += aa * (3 - (y << 1));
}
-- y;
glVertex2i ( x, y);
glVertex2i (-x, -y);
glVertex2i (-x, y);
glVertex2i ( x, -y);
}
glEnd ();
glPopMatrix ();
} void display (void)
{
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity ();
glColor3f (1.0f, 0.0f, 0.0f);
// draw a ellipse
drawEllipse (200, 300, 50, 50);
glutSwapBuffers ();
} void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
if (w <= h)
{
gluOrtho2D (-600.0, 600.0, -600.0 * (GLfloat) h / (GLfloat) w, 600.0 * (GLfloat) h / (GLfloat) w);
}
else
{
gluOrtho2D (-600.0 * (GLfloat) w / (GLfloat) h,600.0 * (GLfloat) w / (GLfloat) h, -600.0, 600.0);
}
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 27: // 'VK_ESCAPE'
exit (0);
break;
default:
break;
}
}
int main (int argc, char ** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (600, 600);
glutCreateWindow ("Bresenham ellipse");
init ();
glutReshapeFunc (reshape);
glutDisplayFunc (display);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}

Bresenham画椭圆算法的更多相关文章

  1. Bresenham画线算法

    [Bresenham画线算法] Bresenham是一种光栅化算法.不仅可以用于画线,也可以用用画圆及其它曲线. 通过lower与upper的差,可以知道哪一个点更接近线段: 参考:<计算机图形 ...

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

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 50 ...

  3. Bresenham直线算法与画圆算法

    在我们内部开发使用的一个工具中,我们需要几乎从 0 开始实现一个高效的二维图像渲染引擎.比较幸运的是,我们只需要画直线.圆以及矩形,其中比较复杂的是画直线和圆.画直线和圆已经有非常多的成熟的算法了,我 ...

  4. Bresenham画直线,任意斜率

    function DrawLineBresenham(x1,y1,x2,y2) %sort by x,sure x1<x2. if x1>x2 tmp=x1; x1=x2; x2=tmp; ...

  5. 两种画线算法(DDA&Bersenham)

    DDA(digital differential analyzer) 由直线的斜截式方程引入 对于正斜率的线段,如果斜率<=1,则以单位x间隔(δx=1)取样,并逐个计算每一个y值 Yk+1 = ...

  6. 计算机图形学DDA画线法+中点画线法+Bresenham画线法

    #include <cstdio> #include <cstring> #include <conio.h> #include <graphics.h> ...

  7. Bresenham快速画直线算法

    现在的计算机的图像的都是用像素表示的,无论是点.直线.圆或其他图形最终都会以点的形式显示.人们看到屏幕的直线只不过是模拟出来的,人眼不能分辨出来而已.那么计算机是如何画直线的呢,其实有比较多的算法,这 ...

  8. Canvas画椭圆的方法

    虽然标题是画椭圆,但是我们先来说说Canvas中的圆 相信大家对于Canvas画圆都不陌生   oGC.arc(400, 300, 100, 0, 2*Math.PI, false); 如上所示,直接 ...

  9. [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)

    上一节链接:http://www.cnblogs.com/zjutlitao/p/4116783.html 前言: 在上一节中我们已经大致介绍了该软件的是什么.可以干什么以及界面的大致样子.此外还详细 ...

随机推荐

  1. python机器学习实战(一)

    python机器学习实战(一) 版权声明:本文为博主原创文章,转载请指明转载地址 www.cnblogs.com/fydeblog/p/7140974.html  前言 这篇notebook是关于机器 ...

  2. xhr.readyState就绪状态

    0:初始化,XMLHttpRequest对象还没有完成初始化 1:载入,XMLHttpRequest对象开始发送请求 2:载入完成,XMLHttpRequest对象的请求发送完成 3:解析,XMLHt ...

  3. 将ArrayList<HashMap<String, String>>转为ArrayList<Bundle>类型的解决方案

    Bundle是一种利用键值对存储的数据格式,而我们在程序中通常利用HashMap存储数据.在开发中,通过Http请求得到JSONArray类型的返回值,我选择利用ArrayList<HashMa ...

  4. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  5. CJOJ 2044 【一本通】最长公共子序列(动态规划)

    CJOJ 2044 [一本通]最长公共子序列(动态规划) Description 一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X,则另一序列Z是X的子序列是指存在一个 ...

  6. CentOS-7.2安装Ambari-2.4.2

    一,Ambari 是什么? Ambari 跟 Hadoop 等开源软件一样,也是 Apache Software Foundation 中的一个项目,并且是顶级项目.目前最新的发布版本是 2.4.2. ...

  7. FreeRTOS——中断管理

    1. 只有以“FromISR”或"FROM_ISR"结束的API函数或宏才可以在中断服务函数中使用. 2. 除互斥信号量外,所有类型的信号量都可以调用 xSemaphoreTake ...

  8. ARKit 初体验

    ARKIT是苹果公司在今年发布的一个AR开发包,用于现有的IOS设备,是的,就是用在手机或者平板上,类似于pokemon go的效果.看了下演示视屏,嗯,看起来很厉害. 对于一个资深软粉,居然被要求研 ...

  9. 初学Python(二)——数组

    初学Python(二)——数组 初学Python,主要整理一些学习到的知识点,这次是数组. # -*- coding:utf-8 -*- list = [2.0,3.0,4.0] #计算list长度 ...

  10. 仿PC版微信的练手项目(可实时通讯)

    仿PC版微信的DEMO 本项目是由一个仿PC版微信的vue前端项目,和一个使用leancloud进行数据存储的.提供WebSocket的node后端项目构成. 本项目使用的技术栈:vue + vue- ...