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

算法步骤:

(1) 输入直线的两端点P0 (x0, y0)和P1 (x1, y1)。

(2) 计算初始值dx, dy, e = -dx, x = x0, y = y0。

(3) 绘制点 (x, y)。

(4) e更新为e+2 * dy。判断e的符号,若e > 0, 则(x, y)更新为(x+1, y+1), 同时将e更新为e-2*dx;否则(x, y)更新为(x+1, y)。

(5) 当直线没有画完时,重复步骤(3)和(4)否则结束。

水平、垂直和|k| = 1的直线可以直接装入帧缓冲存储器面无须进行画线算法处理。下面是我的算法,如有错误请指出。

#include <GL/freeglut.h>
void init (void)
{
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
} void drawLine (int x1, int y1, int x2, int y2)
{
int x, y, dx, dy, e;
// k does not exist
if (x1 == x2)
{
if (y1 < y2)
{
y = y1;
glBegin (GL_POINTS);
while (y <= y2)
{
glVertex2i (x1, y);
++ y;
}
glEnd ();
} // if (y1 < y2)
else
{
y = y2;
glBegin (GL_POINTS);
while (y <= y1)
{
glVertex2i (x1, y);
++ y;
}
glEnd ();
}
} // if (x1 == x2)
else if (y1 == y2) // k = 0
{
if (x1 < x2)
{
x = x1;
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y1);
++ x;
}
glEnd ();
} // if (x1 < x2)
else
{
x = x2;
glBegin (GL_POINTS);
while (x <= x1)
{
glVertex2i (x, y1);
++ x;
}
glEnd ();
}
}
else
{
if (x1 > x2)
{
int temp = x1;
x1 = x2;
x2 = temp;
temp = y1;
y1 = y2;
y2 = temp;
}
x = x1;
y = y1;
dx = x2 - x1;
dy = y2 - y1;
// k = 1
if (dx == dy)
{
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
++ y;
}
glEnd ();
}
else if (dx == -dy) // k = -1
{
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
-- y;
}
glEnd ();
}
else if (dy > dx) // k > 1
{
glBegin (GL_POINTS);
dx <<= 1;
e = - dy;
dy <<= 1;
y = y1 > y2 ? y2 : y1;
int maxY = y1 > y2 ? y1 : y2;
while (y <= maxY)
{
glVertex2i (x, y);
++ y;
e += dx;
if (e > 0)
{
++ x;
e -= dy;
}
}
glEnd ();
}
else if (dy > 0) // 0 < k < 1
{
e = -dx;
dx <<= 1;
dy <<= 1;
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
e += dy;
if (e > 0)
{
e -= dx;
++ y;
} }
glEnd ();
}
else if (-dy < dx) // 0 > k > -1
{
e = -dx;
dx <<= 1;
dy <<= 1;
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
e += dy;
if (e < 0)
{
-- y;
e += dx;
}
}
glEnd ();
}
else if (-dy > dx) // k < -1
{
e = dy;
dx <<= 1;
dy <<= 1;
glBegin (GL_POINTS);
y = y1 > y2 ? y1 : y2;
int minY = y1 > y2 ? y2 : y1;
while (y >= minY)
{
glVertex2i (x, y);
-- y;
e += dx;
if (e > 0)
{
++ x;
e += dy;
}
}
glEnd ();
}
}
} void display (void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 0.0f, 0.0f);
// Vertical line
drawLine (0, -200, 0, 200);
// Horizontal line
drawLine (-200, 0, 200, 0);
// k = 1 line
drawLine (-200, -200, 200, 200);
// k = -1 line
drawLine (-200, 200, 200, -200);
// k = 1/2 line
drawLine (200, 100, -200, -100);
// k = 2 line
drawLine (-100, -200, 100, 200);
// k = -1/2 line
drawLine (-200, 100, 200, -100);
// k = -2 line
drawLine (-100, 200, 100, -200); drawLine (30, 120, 10, 70); drawLine (10, 70, 30, 10); drawLine (30, 10, 60, 50); drawLine (60, 50, 80, 10); drawLine (80, 10, 120, 80); drawLine (120, 80, 70, 80); drawLine (70, 80, 30, 120); 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 ("optimized Bresenham line");
init ();
glutReshapeFunc (reshape);
glutDisplayFunc (display);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}

改进的Bresenham算法的更多相关文章

  1. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  2. Python使用DDA算法和中点Bresenham算法画直线

    title: "Python使用DDA算法和中点Bresenham算法画直线" date: 2018-06-11T19:28:02+08:00 tags: ["图形学&q ...

  3. [计算机图形学]光栅化算法:DDA和Bresenham算法

    目录 一.DDA 二.Bresenham 三.绘制图形 1. 绘制直线 2. 绘制圆 3. 绘制椭圆 一.DDA DDA算法是最简单的直线绘制算法.主要思想是利用直线的斜截式:\(y=kx+b\) 对 ...

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

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

  5. 《图形学》实验六:中点Bresenham算法画圆

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

  6. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  7. 倒排索引压缩:改进的PForDelta算法

    由于倒排索引文件往往占用巨大的磁盘空间,我们自然想到对数据进行压缩.同时,引进压缩算法后,使得磁盘占用减少,操作系统在query processing过程中磁盘读取效率也能提升.另外,压缩算法不仅要考 ...

  8. 大话数据结构(十二)java程序——KMP算法及改进的KMP算法实现

    1.朴素的模式匹配算法 朴素的模式匹配算法:就是对主串的每个字符作为子串开头,与要连接的字符串进行匹配.对主串做大循环,每个字符开头做T的长度的小循环,直到成功匹配或全部遍历完成为止. 又称BF算法 ...

  9. 利用canvas实现的中点Bresenham算法

    Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别,具体的实现过程大家可以去问度娘.我主要是利用canvas画布技术实现了这个 ...

随机推荐

  1. mysql性能监控工具

    参考文档: http://www.linuxidc.com/Linux/2012-09/70459.htm 1.记录慢查询SQL #配置开启 (linux)修改my.cnf: log-slow-que ...

  2. SpringMvc多视图配置(jsp、velocity、freemarker) velocity在springmvc.xml配置VelocityViewResolver,VelocityConfigurer,FreeMarkerConfigurer,FreeMarkerViewResolver

    ?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springf ...

  3. Machine Learning and Data Mining Lecture 1

    Machine Learning and Data Mining Lecture 1 1. The learning problem - Outline     1.1 Example of mach ...

  4. Chrome浏览器扩展开发系列之一:初识Google Chrome扩展

    1.       Google Chrome扩展简介 Google Chrome扩展是一种软件,以增强Chrome浏览器的功能. Google Chrome扩展使用HTML.JavaScript.CS ...

  5. Spring MVC 表单验证

    1. 基于 JSR-303(一个数据验证的规范): import javax.validation.constraints.Min; import javax.validation.constrain ...

  6. 字符的读写函数:fgetc()和fputc()

    fgetc();    功能:    从文件中读取字符.    头文件:  #include <stdio.h>    函数原型:int fgetc(FILE *stream);    返 ...

  7. vim的tab键设定

    多在windows上编程的童鞋可能习惯于感受tab键为4个空格的长度,不过在linux系统中一般默认设定tab键为8个空格长度来显示.事实上tab也确实是8个空格的长度.不过由于习惯问题,某些童鞋还是 ...

  8. Python爬虫番外篇之Cookie和Session

    关于cookie和session估计很多程序员面试的时候都会被问到,这两个概念在写web以及爬虫中都会涉及,并且两者可能很多人直接回答也不好说的特别清楚,所以整理这样一篇文章,也帮助自己加深理解 什么 ...

  9. ASP.NET Core之跨平台的实时性能监控(2.健康检查)

    前言 上篇我们讲了如何使用App Metrics 做一个简单的APM监控,最后提到过健康检查这个东西. 这篇主要就是讲解健康检查的内容. 没看过上篇的,请移步:ASP.NET Core之跨平台的实时性 ...

  10. (转)Spring定时任务的几种实现

    Spring定时任务的几种实现 博客分类: spring框架 quartzspringspring-task定时任务注解  Spring定时任务的几种实现 近日项目开发中需要执行一些定时任务,比如需要 ...