计算机图形学03一一OpenGL 线的形成解析 和 DDA算法

画线 有3种模式


glBegin(GL_LINES); //这个是用来显示要输出的图元的类型
glVertex2i(10,20);
glVertex2i(10,40);
glVertex2i(20,20);
glVertex2i(20,40);
glVertex2i(30,20);

glEnd();


GL_LINES 模式
2个 2个成一条线 线线之间是没有关系的 如果是奇数 最后一个点将不被绘制 如图1




GL_LINE_STRIP 模式
这个是从开始点一个点连接每一个点 最后一个点不跟第一个点连接 如图2


GL_LINE_LOOP 模式
这个是开始点连接每一个点 最后一个点连接第一个点 如图3


那么它是怎么画的呢
屏幕是由像素点构成 他是没有浮点数的 所以绘图时候会受到像素间距限制 
在低的分辨率下你会看到明显的抗锯齿效果


现在熟悉下直线方程 y = m * x + b  m:是斜率 b:是在Y轴上的截距
画线有2个点 p1(x1,y1) p2(x2,y2)
m =  (y2 - y1)/(x2 - x1)这样就可以求的斜率


斜率你知道之后 就可以的 x1 - x2 之间所有点对应的 Y值


通过x 取得y  : y = m* x;


通过y 取得x  : x = y / m


为什么要写这2个呢? 
因为|m| < 1 说明 线在水平上有点偏 所以求Y 才用 y = m* x;
    |m| > 1 说明 线很斜他比较跟Y轴靠近 所以求X 采用 x = y / m
为什么要用2个不同的呢
因为屏幕绘图收到像素的间距的限制 所以我们会采用最靠近像素的点为
这个线的点 那么比如当斜率很大  我们才用y = m* x; 
x会单位递增 m 值是比较大的 那么Y 相对的值是不是比较大 那么这像素点看起来就不光滑
如果采用x = y / m   那么 y单位递增 m值是大的 对应的x值比较小 那么就比较好了

知道怎么绘制2个点之间的值之后我们来看看他用的算法
DDA算法 是一种线段扫描转换算法 基于 y = m* x; x = y / m 计算对应的 X Y 值
在一个坐标轴上以单位间隔对线段取样(x++ 这样的 X是整形哦屏幕坐标都是整形) 从而确定另一个
坐标轴上最靠近线段对应的整数值


也就是 当正斜率 m <= 1   我们就要从用y = m* x
y值 = y的上一个值 + m (为什么加上m呢  y=mx 这个东西因为是x是1 所以Y 每次递增 m)
        当正斜率 m > 1    我们就要从用x = y / m
x值 = x的上一个值 + (1/m) (x = y / m 这个东西因为是y是1 所以X 每次递增 1/m)


那负的斜率了一样的主要是用哪一个方程 y = m* x; x = y / m 当斜率绝对值小于1 说明比较靠近X轴就用y = m* x
y值 = y的上一个值 + m  来求值 m 是负的他会自己减


DDA算法函数:

//这个是为了计算偏差 看看a 向哪一个值靠近
inline int round(const float a)
{
return int(a + 0.5);
}


void lineDDA(int x0,int y0,int xEnd,int yEnd )
{
int dx = xEnd - x0;
int dy = yEnd - y0;
int steps , k;


float xIncrement,yIncrement,x = x0, y = y0;


if (fabs((float)dx) > fabs((float)dy))//取绝对值
{
steps = fabs((float)dx);
}
else
{
steps = fabs((float)dy);
}
//假设 X比较大 也就是说斜率小于 1   xIncrement = 1  yIncrement = m = (yEnd - y0)/(xEnd - x0) 
//   X比较小 也就是说斜率大于 1   xIncrement = (xEnd - x0)/(xEnd - x0) = 1/m
xIncrement = float(dx)/float(steps);
yIncrement = float(dy)/float(steps);


//setPixed(round(x),round(y));
for (int i = 0; i < steps; i++)
{
x += xIncrement;
y += yIncrement;
//setPixed(round(x),round(y));
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值