图形学中的画线算法之 "DDA"算法

  DDA算法画直线,其理论依据:如 m 表示直线斜率, 那么有斜率 m  =  (y2 - y1) / (x2 - x1),  

  ∴ m = Δy / Δx ,   从而有对于沿直线给定的 x 任何增量Δx,计算出对应的y的增量  Δy = m • Δx ;  同理: Δx = Δy / m;

     假设斜率  |m| <= 1;即 x 的长度大于  y的长度。现以 x 单位间距为增量,逐个计算  y 值, 有: yk+1 = yk + m;

     同理,对于|m| > 1; 我们有: xK+1 = yK + 1 / m;   

  (注意: m为斜率,可正可负);

 

  有了上面的数学依据,画线的流程应该很清楚了。假如有两个点(x1, y1)和 (x2, y2); 计算出 detaX 和detaY, 绝对值大的确定我们所要绘制的步数 steps。 依次增加 增量 m  来达到我们画线的目的,

  代码如下:

  1 // gltest.cpp : 定义控制台应用程序的入口点。
  2 //
  3 #include "StdAfx.h"
  4 #include "stdio.h"
  5 #include <iostream>
  6 #pragma comment(lib,"glew32.lib")
  7 #include <gl/glew.h>
  8 #include <gl/glut.h>
  9 
 10 using namespace std;
 11 
 12 static void dda_draw_line(int x0, int y0, int x1, int y1);
 13 void renderScene(void);
 14 static int round(const float x);
 15 static void drawPixel(int x, int y);
 16 static void draw_init(void);
 17 
 18 void renderScene(void)  
 19 {  
 20     glClearColor(1,1,1,1);
 21     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
 22     dda_draw_line(10, -80, 200, 150);
 23     //drawPixel(100, 100);
 24 }
 25 
 26 static int round(const float x)
 27 {
 28     return (int)(x + 0.5);
 29 }
 30 
 31 static void drawPixel(int x, int y)
 32 {
 33     glBegin(GL_POINTS);
 34         glVertex2i(x, y);
 35     glEnd();
 36 }
 37 
 38 static void draw_init(void)
 39 {
 40     glMatrixMode(GL_PROJECTION);
 41     gluOrtho2D(-400, 400, -300, 300);
 42     glPointSize(2.0f);
 43     glColor3f(1,0,0);
 44 }
 45 
 46 static void dda_draw_line(int x0, int y0, int x1, int y1)
 47 {
 48     int dx = abs(x1 - x0);
 49     int dy = abs(y1 - y0);
 50     float steps;
 51     float x = x0, y = y0;
 52     float ad;
 53     float xIncrement, yIncrement;
 54 
 55     cout<< "dx: "<<dx << ", dy:" <<dy <<endl;
 56 
 57     if(dx >= dy)
 58     {
 59         steps = dx;
 60     }
 61     else 
 62     {
 63         steps = dy;
 64     }
 65 
 66     cout<<"step: " << steps <<endl;
 67 
 68     xIncrement = dx / steps;
 69     yIncrement = dy / steps;
 70 
 71     cout<<"xIn: " << xIncrement << " , yIn: " << yIncrement <<endl;
 72 
 73     drawPixel(round(x), round(y));
 74     for(int i = 0; i < steps; i++)
 75     {
 76         //cout<<"x: " <<x << ", y: " <<y<<endl;
 77         x += xIncrement;
 78         y += yIncrement;
 79         drawPixel(round(x), round(y));
 80     }
 81     glutSwapBuffers();  
 82 
 83 }
 84 
 85 int main(int argc, char* argv[])
 86 {
 87     glutInitWindowSize(800, 600);
 88     glutInitWindowPosition(500,200);
 89     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
 90     glutInit(&argc, argv);
 91     glutCreateWindow("hello opengl");
 92 
 93     draw_init();
 94 
 95 
 96     printf("opengl version; %s\n", glGetString(GL_VERSION));
 97     printf("glsl version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
 98 
 99     glutDisplayFunc(renderScene);  
100     glutMainLoop();
101     return 0;
102 
103 }

 

posted on 2015-07-22 11:29  宇智波.鼬  阅读(1235)  评论(0编辑  收藏  举报

导航