bresenham算法是一种光栅化的直线生成算法,是计算机图形学目前使用广泛的直线扫描转换算法,具体逻辑很简单,就是描点。所以bresenham的算法研究实际上是研究目标点的选择。
实验环境:
openGL,visual studio 2019
算法原理:
设直线方程为y=kx+b,误差项为d并初始化为0。则每当x每增加1时,y的值是否增加1取决于d与0.5比较的大小,由y=k(x+1)+b得y的增量为斜率k,故d=d+k。当d大于等于0.5时,下一像素点取值为右上方的点(x+1,y+1),当d小于0.5时,则取下一像素点为(x+1,y)。设e=d-0.5,上述比较等同于e与0的比较。当e大于0,置新的e=e-1,当e小于0,e=e+k。
一些改进:
在上述算法过程计算直线斜率和误差项时使用了小数和除法,可以令e’=2*e*dx这样改用整数避免除法。比较e大于等于0时e=e+2*dy,小于0时e=e-2*dx。
完整代码:
#include<iostream>
#include <GL/glut.h>
#include <math.h>
using namespace std;
float Bres_Line(int x1, int y1, int x2, int y2)
{
int i, x, y, dx, dy, e;
dx = abs(x2 - x1);
dy = abs(y2 - y1);
if (dx > dy)
{
swap(x1, y1);
swap(x2, y2);
dx = abs(x2 - x1);
dy = abs(y2 - y1);
}
int k = dy / dx;
e = -0.5;
x = x1;
y = y1;
for (i = 0; i <= dx; i++)
{
glVertex2f(x, y);
x++;
e = e + k;
if (e >= 0)
{
y = y + 1;
e = e - 1;
}
}
return x, y;
}
void myDisplay()
{
glBegin(GL_LINES);
glColor3f(0.0, 1.0, 0.0);
Bres_Line(300, 200, 100, 100);
glEnd();
glFlush();
}
void Init()
{
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(300, 300);
glutInitWindowSize(500, 500);
glutCreateWindow(" ");
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}