Digital Differential Analyzer (DDA) 数值微分法 绘制直线
优点:逻辑简单,直观
缺点:过多的浮点数处理
要点:对其中的乘法运算可以加以改进成为加法运算(硬件上执加法运算更速度快于乘法运算)
yk+1=kx+1+b = k(x1+δx)+b = kx1+b+kδx = y1+kδx
当δx等于1时,纵轴方向增量为常数k
完整的OpenGL代码:
#ifndef GLUT_DISABLE_ATEXIT_HACK
#define GLUT_DISABLE_ATEXIT_HACK
#endif
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
// 颜色
typedef struct _color
{
float r, g, b;
float alpha;
}ColorRGBA;
// 2D顶点
typedef struct _point
{
float x;
float y;
ColorRGBA color;
}Point2D;
Point2D gStart;
Point2D gEnd;
/* 备注:
*
* 已修改为适应任何顶点的DDA直线算法
*/
void DDALine(Point2D* start, Point2D* end)
{
float dx, dy;
float k;
Point2D* START; // 起始顶点标记
Point2D* END; // 终止顶点标记
if(end->x < start->x)
{
START = end;
END = start;
}
else
{
START = start;
END = end;
}
k = (END->y - START->y)/(END->x - START->x);
// 初始化
dx = START->x;
dy = START->y;
if( abs(k) <= 1 )
{
dx = (int)dx;
for(; dx <= END->x; dx++)
{
::glVertex3i(dx, (int)dy, 0);
dy = dy + k;
}
}
if( abs(k) > 1 )
{
dy = (int)dy;
for(; dy <= END->y; dy++)
{
::glVertex3i((int)dx, dy, 0);
dx = dx + 1/k;
}
}
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glOrtho(0.0, 500.0, 0.0, 500.0, -500.0, 500.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POINTS);
// 画直线
DDALine(&gStart, &gEnd);
glEnd();
glFlush();
}
int main(int argc, char **argv)
{
printf("Set start position & end position :");
scanf("%f%f%f%f", &gStart.x, &gStart.y, &gEnd.x, &gEnd.y);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Line Algorithms");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
备注:已修改为适应任意顶点位置的DDA直线算法,调整 glOrtho() API 参数可以模拟显示器分辨率的高低,
这样一来可以更近距离的观察顶点是怎样生成直线的。
高分辨率:
低分辨率: