CG Foundation - DDA (OpenGL)

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 参数可以模拟显示器分辨率的高低,

这样一来可以更近距离的观察顶点是怎样生成直线的。


高分辨率:



低分辨率:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值