计算机图形学上机(一)改进的DDA算法

改进DDA:

基于VS2019,调用OPENGL的改进DDA算法,在原来的DDA算法上将划线的部分进行了修改,代码是基于在网上找到的DDA算法进行修改。改掉的部分基本属于文献中直接复制引用。写出来并不费劲,但需要自己进行理解体会。


原理分析:

令 d 表示 y+0.5的小数部分, 因此在区间[0,1)上,小数部分d是以k为增量的单调递增序列;而k>0,则d在经 过一定次数的递增后必然会有d≥ 1,此时 只要令d=d-1,d必然会重新变成区间[0,1) 上的实数。通过以上分析, 可以将直线划分为m 段:L0 ,L1 ,L2…L m-1;每一段上像素点的y+0.5的小数部分 d 都是区间[0,1)上的单调递增序列。因此只要绘制出小数为 di 时候的像素 点然后通过水平移动即可得到多个像素点。
例:绘制(0,0) (10,2)的直线 该直线的斜率为0.2
从表 1 中可看出,根据小数的变化规律 可将该直线分为 3 段分别绘制。 d 有 3 个单调递增的序列,分别是{0.5, 0.7,0.9},{0.1,0.3,0.5,0.7,0.9},{0.1,0. 3,0.5}。 则可将这 11 个像素点分成 3 段输出。在这里插入图片描述


代码如下,注释掉的部分即最开始的DDA算法
#include<math.h>
#include<gl/glut.h>
#include<iostream>
using namespace std;

void myDisplay(void);//调用lineDDA
void setPixel(int x, int y);//在OpenGL中可以用glVertex来实现
int around(const float a);
void ChangeSize(GLsizei w, GLsizei h);
void ddaline(int x0, int y0, int xEnd, int yEnd);

void myDisplay(void) {
	ddaline(50, 50, 150, 70);
}

void setPixel(int x, int y) {
	//用OpenGL自己的函数实现书上的setPixel
	glPointSize(5.0f);
	glBegin(GL_POINTS);
	glVertex2i(x, y);
	glEnd();
	glFlush();
}

int around(const float a) {
	return int(a + 0.5);
}

//窗口大小改变时调用的登记函数
void ChangeSize(GLsizei w, GLsizei h) {
	if (h == 0)
		h = 1;
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	if (w <= h)
		glOrtho(0.0f, 250.0f, 0.0f, 250.0f * h / w, 1.0, -1.0);
	else
		glOrtho(0.0f, 250.0f * w / h, 0.0f, 250.0f, 1.0, -1.0);
}

//void lineDDA(int x0, int y0, int xEnd, int yEnd) {
//	glPointSize(3.0f);//设置像素点大小
//	int dx = xEnd - x0, dy = yEnd - y0, steps, k;
//	float xIncrement, yIncrement, x = x0, y = y0;
//	if (abs(dx) > abs(dy))//确定步长,谁大就取谁
//		steps = abs(dx);
//	else
//		steps = abs(dy);
//	xIncrement = float(dx) / float(steps);//增量当中有一个会为1,另一个会为斜率k
//	yIncrement = float(dy) / float(steps);
//	setPixel(around(x), around(y));//由于每次都加了小于1的增量,所以需要取整
//	for (k = 0; k < steps; k++) {
//		x += xIncrement;
//		y += yIncrement;
//		setPixel(around(x), around(y));
//	}
//}

void ddaline(int x0, int y0, int x1, int y1)
{
	int x = x0, t, m; /* m 为直线的段数 */
	float k, dx, dy, d;
	dx = x1 - x0;
	dy = y1 - y0;
	k = dy / dx;
	d = 0.5;
	for (m = 0;; m++)
	{
		t = y0 + m;
		while (d < 1)
		{
			setPixel(x++, t);
			d = d + k;
			if (x > x1) break;
		}
		if (x > x1) break;
		d = d - 1;
	}
}

int main(int argc, char* argv[]) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(200, 200);
	glutInitWindowSize(400, 400);
	glutCreateWindow("输入线");
	glutDisplayFunc(&myDisplay);
	glutReshapeFunc(ChangeSize);
	glutMainLoop();
	return 0;
}

        }

opengl的配置https://blog.csdn.net/lofone/article/details/103625169?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162071928216780265452111%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162071928216780265452111&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-8-103625169.pc_search_result_cache&utm_term=opengl+VS2019&spm=1018.2226.3001.4187
改进的直线DDA算法_王茂华https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&dbname=CJFD2009&filename=ZXLJ200904215&v=2ePGOQYw%25mmd2FGPOAWV4DbCZIVUD%25mmd2BMYHUeU02%25mmd2BbAyy5ponc8BujkXBkT9WXQ7gR6Df7S

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值