您的位置:首页 > 理论基础

计算机图形学-直线的生成算法

2017-09-27 21:08 429 查看
直线的生成算法一共有四种:数值微分法(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<gl/glut.h>
#include<math.h>

//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;
}


效果图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: