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

算法步骤:

(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. Java基础语法<三> 输入输出

    1. 读取输入 Scanner in = new Scanner(System.in);   输入一行(包含空格) String str = in.nextLine()   读取一个单词(以空白符作为 ...

  2. 大数据平台常见异常-zookeeper

    本文主要阐述大数据平台环境zookeeper常见异常和解决方案 1.Connection reset by peer异常 异常说明 我们现在项目有个任务OneMinuteDataSync是用spark ...

  3. Eclipse中常用快捷键

    Ctrl+C:复制. Ctrl+V:粘贴. Ctrl+X:剪切. Ctrl+S:保存. Ctrl+Z:撤销. Ctrl+A:全选. F3:快速定位光标位置的某个类.方法和属性. Ctrl+Q:跳到最后 ...

  4. Java基础语法<八> 继承

    1.超类和子类 超类和子类 父类与子类 多态: 一个对象变量可以指示多种实际类型的现象称为多态 一个变量可以引用父类对象,也可以引用其子类对象,这就是多态. 不能将一个超类的引用赋给子类变量,因为调用 ...

  5. Scala关于软件的安装

    1.安装JDK 因为很多系统都会预装java,所以我们首先要测试Java版本.这里我们要求要在1.8以上.在终端输入java -version来测试版本 Windows 关于Windows,我们首先要 ...

  6. Spring Boot 1.5.4集成Redis

    本文示例源码,请看这里: 如何安装与配置Redis,请看这里 首先添加起步依赖: <dependency> <groupId>org.springframework.boot& ...

  7. (转)Linux 下 查看以及修改文件权限

    场景:Linux环境下远程部署项目,发现因为文件权限问题,不能执行远端的可执行文件.问题还没解决,待议... 1 查看权限 在终端输入: ls -l xxx.xxx (xxx.xxx是文件名) 那么就 ...

  8. (转)每天一个linux命令(50):crontab命令

    场景:在学习Linux环境下自动部署项目时候,可以通过crontab命令设定定时任务,实现服务端项目的自动部署! 前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系 ...

  9. (转)Memcached 在windows下的java使用

    Memcached 在windows下的java使用   研究这个东东主要是为了解决在教务管理中选课系统的大并发情况下数据库频繁读写造成速度慢的问题,但要使用WEB服务器的内存,是不是可靠还需要验证, ...

  10. [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]

    历尽艰辛终于A掉了这题QwQ 贴COGS评论区几句话=.= 策爷:"splay/块状链表的自虐题.".深刻理解到如果没有M倾向就不要去写这题了.. -Chenyao2333 记得b ...