本次实验项目
DDA画线算法理解与运用。
算法介绍
DDA(Digital Differential Analyzer)画线算法是一种基于数值微分原理的直线生成算法。它主要用于在光栅系统中绘制直线,即在像素点阵中生成直线。DDA算法的核心思想是从一个端点开始,通过增量,逐步迭代计算下一个端点的位置,直到达到另一个端点。
算法描述
设直线为L:y=kx+b,已知过端点 P0(x0, y0),P1(xend, yend),若
---------------------------------------------------------------------------------------------------------------------------------
沿X轴步进,
当 | k | <= 1即时,直线L靠近X轴,直线斜率为
所以x每递增1,y相应地递增k,每次计算点的坐标,我只需要x+1,y+k就行了,避免了乘除,而只有加减。通过增量得到下一个点后,可知此坐标肯定会与实际像素点有偏差(实际的直线并不是和像素点完全重合的)。所以采取四舍五入得方式来平衡差值,但是C/C++中取整是直接舍去小数值,所以采取加上0.5再取整,即int(a+0.5)。从而达到一个四舍五入的目的。
---------------------------------------------------------------------------------------------------------------------------------
沿Y轴步进,
当 | k | >= 1即时,直线L靠近Y轴,若仍然使 ,则会导致斜率k大于1。从而在x递增1的时候y可能会出现递增大于1的数,使得像素点不相邻,直线不连续,出现断点的情况。此时应令直线斜率为
y每递增1,x相应地递增v,每次计算点的坐标,我只需要y+1,x+v就行了,同样的通过增量得到下一个点后,可知此坐标肯定会与实际像素点有偏差(实际的直线并不是和像素点完全重合的)。所以采取四舍五入得方式来平衡差值,但是C/C++中取整是直接舍去小数值,所以采取加上0.5再取整,即int(a+0.5)。从而达到一个四舍五入的目的。
---------------------------------------------------------------------------------------------------------------------------------
整合即可得到完整DDA画线算法。
功能简单介绍
setPixel
函数用于在指定的x和y坐标绘制一个像素点。lineDDA
函数实现了DDA算法,它接受两个端点的坐标作为参数,并在这两个点之间绘制直线。算法通过计算x和y的增量,逐步逼近直线上的点,并使用setPixel
函数绘制这些点。
代码
#include <windows.h>
#include <cmath>
#include <GL/glut.h>
#define GLUT_DISABLE_ATEXIT_HACK
inline int round(const float a) {
return (int)(a + 0.5); // 四舍五入
}
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0); // 设置背景色
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 1920.0, 0.0, 1080.0); // 设置坐标系
}
void setPixel(int x, int y) {
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
}
void lineDDA(int x0, int y0, int xEnd, int yEnd) {
int dx = xEnd - x0;
int dy = yEnd - y0;
int steps = (fabs(dx) > fabs(dy)) ? fabs(dx) : fabs(dy);
float xIncreament = float(dx) / float(steps);
float yIncreament = float(dy) / float(steps);
float x = x0;
float y = y0;
setPixel(round(x), round(y)); // 设置起点像素
for (int k = 0; k < steps; k++) {
x += xIncreament;
y += yIncreament;
setPixel(round(x), round(y)); // 绘制像素点
}
}
void lineSegment(void) {
glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓存
//坐标轴
glColor3f(1.0, 1.0, 1.0); // 设置线条颜色为白色
glPointSize(5);
lineDDA(960, 0, 960, 1080);//y轴
lineDDA(940,1050,960,1080);
lineDDA(980,1050,960,1080);
lineDDA(990,1070,1005,1050);
lineDDA(1020,1070,990,1000);
lineDDA(0, 540, 1920, 540);//x轴
lineDDA(1900,560,1920, 540);
lineDDA(1900,520,1920, 540);
lineDDA(1860,510,1910, 460);
lineDDA(1910,510,1860, 460);
//绘制直线-1
glColor3f(1.0, 0.0, 1.0); // 设置线条颜色为紫色
glPointSize(3);
lineDDA(50, 50, 1850, 1000);
//绘制直线-2
glColor3f(1.0, 1.0, 0.0); // 设置线条颜色为黄色
glPointSize(3);
lineDDA(400,1000,1880,300);
//绘制直线
glColor3f(0.0, 1.0, 1.0); // 设置线条颜色为青色
glPointSize(3);
lineDDA(400,1000,400,20);
glFlush(); // 强制执行所有OpenGL命令
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(600, 450);
glutInitWindowSize(1920, 1080);
glutCreateWindow("DDA-OpenGL");
init();
glutDisplayFunc(lineSegment);
glutMainLoop();
return 0;
}
运行结果
上手实践
各位学有余力的先生和女士,如有兴趣的话,不妨参考上面内容,动手绘制自己喜欢的图形吧!祝你成功。
标签:直线,1.0,OpenGL,int,0.0,float,图形学,C语言,lineDDA From: https://blog.csdn.net/2303_77716250/article/details/143663452