直线的DDA算法的C实现(opengl实现)

 
 
 
 
 
// DigitalDifferentialAnalyserLine.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include<stdlib.h>
#include <GL/glut.h>

/* initialization: */
void myinit(void)
{
 
/* attributes */

      glClearColor(1.0, 1.0, 1.0, 0.0); /* white background */
      glColor3f(1.0, 0.0, 0.0); /* draw in red */

/* set up viewing: */
/* 500 x 500 window with origin lower left */

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluOrtho2D(0.0, 500.0, 0.0, 500.0);
      glMatrixMode(GL_MODELVIEW);
}

void dda_line(int xa,int ya,int xb,int yb)
{
		GLfloat delta_x,delta_y,x,y;
		int dx,dy,steps;
		dx=xb-xa;
		dy=yb-ya;
		if(abs(dx)>abs(dy))
				steps=abs(dx);
		else
				steps=abs(dy);
		delta_x=(GLfloat)dx/(GLfloat)steps;
		delta_y=(GLfloat)dy/(GLfloat)steps;
		x=xa;
		y=ya;
		glClear(GL_COLOR_BUFFER_BIT);
		glBegin(GL_POINTS);
		glVertex3f(x,y,0);
		for(int k=1;k<=steps;k++)
		{
				x+=delta_x;
				y+=delta_y;
				glBegin(GL_POINTS);
                glVertex3f(x,y,0); 
                glEnd();
		}
		
}

/* the display callback: */
void display( void )
{
    glClear(GL_COLOR_BUFFER_BIT);  /*clear the window */

    /*----------------------------------------*/
    /*  viewport stuff                        */
    /*----------------------------------------*/
    /* set up a viewport in the screen window */
    /* args to glViewport are left, bottom, width, height */
    glViewport(0, 0, 500, 500);
    /* NB: default viewport has same coords as in myinit, */
    /* so this could be omitted: */

    
    dda_line(200,200,2000,2000);

    /* and flush that buffer to the screen */
    glFlush(); 
 }

int main(int argc, char** argv)
{

/* Standard GLUT initialization */

    glutInit(&argc,argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */
    glutInitWindowSize(500,500); /* 500 x 500 pixel window */
    glutInitWindowPosition(0,0); /* place window top left on display */
    glutCreateWindow("Digital Differential  Analyser  Line"); /* window title */
    glutDisplayFunc(display); /* display callback invoked when window opened */
     myinit(); /* set attributes */
    glutMainLoop(); /* enter event loop */
}
 

 

算法介绍部分就直接来自:http://course.cug.edu.cn/cugFirst/computer_graphics/class/course/2-1-1-a.htm

感觉挺麻烦的自己写的话有好多数学公式,但代码是自己的啊!

  设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得

= m =直线的斜率 (2-1)

  可通过计算由x方向的增量x引起y的改变来生成直线:

xi+1=xi+x (2-2)
yi+1=yi+y=yi+x·m (2-3)

  也可通过计算由y方向的增量y引起x的改变来生成直线:

yi+1=yi+y (2-4)
xi+1=xi+x=xi+y/m (2-5)

  式(2-2)至(2-5)是递推的。

 

选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向上的增量为一个象素单位(x=1),然后利用式(2-1)计算另一个方向的增量(y=x·m=m)。通过递推公式(2-2)至(2-5),把每次计算出的(xi+1,yi+1)经取整后送到显示器输出,则得到扫描转换后的直线。

  之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的象素应均匀,这在下图中可看出。

  另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还是负值。

 

 

1、已知直线的两端点坐标:(x1,y1),(x2,y2)
  2、已知画线的颜色:color
  3、计算两个方向的变化量:dx=x2-x1
               dy=y2-y1
  4、求出两个方向最大变化量的绝对值:
               steps=max(|dx|,|dy|)
  5、计算两个方向的增量(考虑了生成方向):
               xin=dx/steps
               yin=dy/steps
  6、设置初始象素坐标:x=x1,y=y1
  7、用循环实现直线的绘制:
    for(i=1;i<=steps;i++)
    { putpixel(x,y,color);/*在(x,y)处,以color色画点*/
     x=x+xin;
     y=y+yin;
    }

 

 

 

你可能感兴趣的:(c,算法,buffer,callback,attributes,initialization)