中点Bresenham 算法及实现
2010-12-04 20:08 风恋残雪 阅读(1466) 评论(0) 收藏 举报这里不仔细讲原理,只是把我写的算法发出来,跟大家分享下,如果有错误的话,还请大家告诉我,如果写的不好,也请指出来,一起讨论进步。
只写出0<=k<=1时的Bresenham算法绘图过程
(1) 输入直线的两端点,P0(x0, y0)和P1(x1, y1).
(2) 计算初始值dx, dy, d = dx - 2 * dy, x = x0, y = y0.
(3) 绘制点(x, y), 判断d的符号。若d < 0, 则(x, y)更新为(x+1, y+1), d更新为d + 2 * dx - 2 * dy;否则(x, y)更新为(x+1, y), d 更新为d - 2 * dy
(4)当直线没有画完时,重复步骤 (3),否则结束。
水平、垂直和|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 dx, dy, d, upInc, downInc, leftInc, rightInc, x, y;
if (x1 == x2)
{
// 斜率 k 不存在
if (y1 < y2)
{
y = y1;
glBegin (GL_POINTS);
do
{
glVertex2i (x1, y);
++ y;
}while (y <= y2);
glEnd ();
}
else
{
y = y2;
glBegin (GL_POINTS);
do
{
glVertex2i (x1, y);
++ y;
}while (y <= y1);
glEnd ();
}
}
else if (y1 == y2)
{
// k = 0
if (x1 < x2)
{
glBegin (GL_POINTS);
x = x1;
do
{
glVertex2i (x, y1);
++ x;
}while (x <= x2);
glEnd ();
}
else
{
glBegin(GL_POINTS);
x = x2;
do
{
glVertex2i (x, y1);
++ x;
}while (x <= x1);
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);
do
{
glVertex2i (x, y);
++ x;
++ y;
}while (x <= x2);
glEnd ();
}
// k == -1
else if (dx == -dy)
{
glBegin (GL_POINTS);
do
{
glVertex2i (x, y);
++ x;
-- y;
}while (x <= x2);
glEnd ();
}
else
{
if (dy > 0)
{
// 0 <k < 1
if (dy < dx)
{
dy <<= 1;
d = dx - dy;
dx <<= 1;
upInc = dx - dy;
downInc = -dy;
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
if (d < 0)
{
++ y;
d += upInc;
}
else
{
d += downInc;
}
}
glEnd ();
}
else
{
// k > 1
dx <<= 1;
d = dx - dy;
dy <<= 1;
rightInc = dx - dy;
leftInc = dx;
glBegin (GL_POINTS);
while (y <= y2)
{
glVertex2i (x, y);
++ y;
if (d > 0)
{
++ x;
d += rightInc;
}
else
{
d += leftInc;
}
} // while
glEnd ();
}
} // if (dy > 0)
else
{
// 0 > k > -1
if (-dy < dx)
{
dy <<= 1;
d = -dx - dy;
dx <<= 1;
downInc = -dx - dy;
upInc = -dy;
glBegin (GL_POINTS);
while (x <= x2)
{
glVertex2i (x, y);
++ x;
if (d > 0)
{
d += downInc;
-- y;
}
else
{
d += upInc;
}
} // while
glEnd ();
} // if (-dy > dx)
else
{
// k < -1
dx <<= 1;
d = -dx - dy;
dy <<= 1;
leftInc = - dx;
rightInc = -dx - dy;
glBegin (GL_POINTS);
while (y >= y2)
{
glVertex2i (x, y);
-- y;
if (d < 0)
{
d += rightInc;
++ x;
}
else
{
d += leftInc;
}
}
glEnd ();
}
}
}
}
}
void display (void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
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 (-200.0, 200.0, -200.0 * (GLfloat) h / (GLfloat) w, 200.0 * (GLfloat) h / (GLfloat) w);
}
else
{
gluOrtho2D (-200.0 * (GLfloat) w / (GLfloat) h,200.0 * (GLfloat) w / (GLfloat) h, -200.0, 200.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 | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutCreateWindow ("Bresenham line");
init ();
glutReshapeFunc (reshape);
glutDisplayFunc (display);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}
作者: 风恋残雪
出处: http://www.cnblogs.com/ghl_carmack
关于作者:专注游戏引擎,关注VR,对操作系统、编译原理有深厚兴趣!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号