自己动手实现光栅化直线生成算法

前期准备:搭建可以在屏幕上画一个像素的开发环境,我使用OpenGL的glfw库来画点。

为了提高画线算法的可读性,我先把自己使用的画点函数写出来

//点 绘制
/*
point2D是一个包含x,y坐标位置的对象 R,G,B - color pointSize是像素点的大小
*/
void drawPoint(point2D point,float R,float G,float B,float pointSize);

常用的直线生成算法有:DDA算法、中值算法、bresenham算法等等

一、为什么要“光栅化”?

在写算法之前,我们先聊一下什么叫光栅化直线。比如我在屏幕上以x、y同时递增0.01的速度,希望画出一条直线

for(float i=0;i<1;i+=0.01)
{
    drawPoint(i,i,1.0, 0.0, 0.0);
}
效果:


但是我们发现这条直线并不“直”,这是因为在计算机的屏幕上,是以类似网格形式的像素点存在的。当我们一以位置(0,0)、(0.01,0.01)(0.02,0.02)(0.03,0.03)...画点时,它不一定会恰好落在我们合适的像素点中,因此直线会产生扭曲。

我们的算法来判断哪个像素点被点亮以接近我们真正的任务,这个过程被称为光栅化。

例如,如我们用DDA画线算法来画这条线,依然以每次0.01的速度递增,图像如下:


我们会发现这条“直线”更“直”,如果我们将像素点调小并将增长速度减小,那么画直线的精度会更大,图像也更接近直线。

这就是软光栅化直线的一个示例。

二、DDA直线生成算法

DDA算法,又称数值微分画线算法,它的算法思想是:

1)每次下一个点距离上一个点X(或Y)方向前进一个距离,另一个方向前进1/k个距离,根据直线的斜率k,确定哪个方向前进1个距离,如果|k|>1,Y前进1个距离,X前进1/k个距离,如果|k|<1,X前进1个距离

2)前进后画点并重进进入步骤1直到画线完成

算法的代码演示

void drawLine_DDA(point2D point1,point2D point2,float R,float G,float B)
{
    float dm = 0,dx = 0,dy = 0;
    if(fabs(point2.x-point1.x) >= fabs(point2.y-point1.y))
    {
        dm = fabs(point2.x-point1.x);
    }else
    {
        dm = fabs(point2.y-point1.y);
    }
    dx = (float)(point2.x-point1.x)/(dm*base);
    dy = (float)(point2.y-point1.y)/(dm*base);
    for(float i=0;i<dm*base;i++)
    {
        point2D tempPoint(point1.x,point1.y);
        drawPoint(tempPoint,R,G,B,mrender_pointSize);
        point1.x+=dx;
        point1.y+=dy;
    }
}
三、中点直线生成算法




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值