计算机图形学-直线的生成算法
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算法
效果图
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; }
效果图
相关文章推荐
- 【计算机图形学】基本图形元素:直线的生成算法
- 计算机图形学—DDA直线生成算法
- 计算机图形学——直线生成算法
- 计算机图形学之--直线生成算法(一)
- 计算机图形学 - 全斜率Bresenham直线生成算法
- 计算机图形学(1)——直线生成算法的实现
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)
- [计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二)
- 计算机图形学 - 球体、环、椭球体生成算法
- 图形学,直线生成算法
- 计算机图形学——生成直线的DDA算法
- 计算机图形学(2)基本图形的生成与显示——直线的生成
- java画直线算法 DDA 计算机图形学
- 计算机图形学基础 : 基本图形生成算法之直线的扫描转换
- 计算机图形学:3种画直线算法(转)
- 【算法】计算机图形学的一些经典小题:判断点在多边形内,随机生成三角形内的点,判断两个矩形是否相交等
- 计算机图形学第五章---基本图形生成算法
- 计算机图形学(二)输出图元_6_OpenGL曲线函数_1_圆生成算法
- 【计算机图形学】基本图形元素:圆的生成算法
- 计算机图形学——直线的三种扫描转换算法