直线的生成算法一共有四种:数值微分法(DDA法),逐点比较法,Bresenham画线法法,中点画线法
1、DDA法:
利用直线微分方程绘制直线
dx=x2-x1 dy=y2-y1; dm=max(|dx|,|dy|);
取时间步长为1/dm;
则x[i+1]=x[i]+dx/dm; y[i+1]=y[i]+dy/dm;
2、逐点比较法
首先平移直线,使y坐标较小的点位于原点
假设要画直线为OA,当前画笔位置为M,偏差d=yM/xM-yA/xA=(yM*xA-yA*xM)/xM*xA; 由于分母恒为正,所以d的正负由分子决定。
递推公式:第一象限:误差公式为FM=yM*xA-yA*xM;
若F(i)>=0,x走+1步,则F(i+1)=F(i)-yA;
若F(i)<0,y走+1步,则F(i+1)=F(i)+xA;
第二象限:FM=-xMyA-(-xA)yM;
若F(i)>=0,y走+1步,则F(i+1)=F(i)-(-xA);
若F(i)<0,x走-1步,则F(i+1)=F(i)+yA;
终点:总步数n=|x2-x1|+|y2-y1|;
3.Bresenham算法
假设所绘制直线的方程为y=mx+b;,判断右边和右上点距离直线的距离
d[i+1]=d[i]+2(dy-dx),d[i]>=0,选择右上; d[i+1]=d[i]+2dy,d[i]<0,向右;
DDL算法与Bresenham算法
#include
#include
//void LineDDA(int x0, int y0, int x1, int y1)
//{
// int x, dy, dx, y;
// float m;
// dx = x1 - x0;
// dy = y1 - y0;
// m = dy/dx;
// y = y0;
// glColor3f(1.0f, 1.0f, 0.0f);
// glPointSize(1);
//for (x = x0; x <= x1; x++)
// {
// glBegin(GL_POINTS);
// glVertex2i(x, (int)(y + 0.5));
// glEnd();
// y += m;
//}
//}
void swap_value(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void Bres_Line(int x1, int y1, int x2, int y2)
{
glColor3f(1.0f, 1.0f, 0.0f);
glPointSize(1);
glBegin(GL_POINTS);
glVertex2i(x1, y1);
glEnd();
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
if (dx == 0 && dy == 0)
return;
int flag = 0;
if (dx < dy)
{
flag = 1;
swap_value(&x1, &y1);
swap_value(&x2, &y2);
swap_value(&dx, &dy);
}
int tx = (x2 - x1)>0 ? 1 : -1;
int ty = (y2 - y1) > 0 ? 1 : -1;
int curx = x1;
int cury = y1;
int dS = 2 * dy;
int dT = 2 * (dy - dx);
int d = dS - dx;
while (curx != x2)
{
if (d < 0)
d += dS;
else
{
cury += ty;
d += dT;
}
if (flag)
{
glBegin(GL_POINTS);
glVertex2i(cury, curx);
glEnd();
}
else
{
glBegin(GL_POINTS);
glVertex2i(curx, cury);
glEnd();
}
curx += tx;
}
}
void myDisPlay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(25.0, 25.0, 75.0, 75.0);
glPointSize(5);
glBegin(GL_POINTS);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.0f, 0.0f);
glEnd();
//LineDDA(0, 0, 200, 300);
Bres_Line(0, 0, 200, 300);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(100.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(180.0f, 240.0f);
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(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("Hellow World!");
Init();
glutDisplayFunc(&myDisPlay);
glutReshapeFunc(&Reshape);
glutMainLoop();
return 0;
}