计算机图形学:直线的光栅化模拟

本文介绍了计算机图形学中直线的光栅化过程,包括通过公式直接计算、DDA算法和Bresenham算法。详细讲解了Bresenham算法的取点原理,并提供了相应的C++代码实现。最后通过旋转直线测试了这些算法的性能和效果。
摘要由CSDN通过智能技术生成

       屏幕是有若干像素点组成的,任何图形画到屏幕上都要先转为像素点,也就是光栅化,下面模拟直线的光栅化。
像素的最小单位为1,且为整数,所以在直线上只能取在X轴或Y轴上步进为1的最接近的整数点,至于是X轴还是Y轴取决于跨度大的轴,假设直线起点为(x1,y1),终点为(x2,y2) ,如果|x2-x1|>=|y2-y1|,即斜率位于-1和1之间,则X轴每次步进一个像素,否则Y轴。
       下面的代码模拟几种光栅化直线的算法,为了方便假设x2>x1>0,y2>y1>0,且斜率位于0到1之间,win32编程中窗口的XY轴正方向分别向右向下,与平常的坐标系不太一样,这里以Windows窗口坐标为准。画直线的时候端点也有可能出现浮点数,所以输入点都使用float类型。在测试下面代码之前首先创建一个Windows桌面应用程序。

1、通过公式直接计算
       下面的函数DrawLine_1在X方向步进1,Y值通过直线的斜截公式算出

void DrawLine_1(HDC hdc, float x1, float y1, float x2, float y2)
{
    //转为斜截式,y=k*x+b,分求出k和b
    float dx = x2 - x1;
    float dy = y2 - y1;
    float k = dy / dx;
    float b = y1 - k * x1;
    int num = dx;//获取点的个数
    int x = round(x1);
    int y = round(x * k + b);
    for (int i = 0; i <= num; i++)
    {
        ::SetPixel(hdc, x, y, RGB(255, 0, 0));
        x += 1;
        y = round(x * k + b);
    }
}

       x值只要在第一次取x1最接近的整数,然后使用整数加1即可,y值每次都要用round函数取整数,取整数还可以用y=x * k + b+0.5的形式,这种方式每次都要使用浮点数的乘法和加法,效率太低。因为x每次加1,y轴增加的值是固定的k,所以只要在前一个准确y值上加k就可以算出当前准确的y值,然后取整,即DDA算法。

2、DDA算法(Digital Differential Analyzer数值微分法)
       DrawLine_2函数中fy为当前x对应的准确的y值,x每次加1,fy的值每次增加斜率k,最终y的值由fy取整

void DrawLine_2(HDC hdc, float x1, float y1, float x2, float y2)
{
    float dx = x2 - x1;
    float dy = y2 - y1;
    int stepx = 1;
    float stepy = dy / dx;
    int num = round(dx);
    int x = round(x1);
    float fy = (x - x1) * dy / dx + y1;//(x-x1)/dx=(y-y1)/dy
    int y = round(fy);
    for (int i = 0; i <= num; i++)
    {
        ::SetPixel(hdc, x, y, RGB(255, 0, 0));
        x += stepx;
        fy += stepy;
        y = rou
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值