计算机图形学---DDA直线画法c#实现

计算机图形学—DDA直线画法c#实现

DDA直线画法,即数值微分法,是计算机图形学中直线段扫描转换的经典算法之一,本篇文章将简单介绍DDA算法,并给出c#实现的代码。


一、DDA直线画法

设直线的斜截式方程为 y i = k i x + b y_i = k_ix + b yi=kix+b
根据微分的思想,可以得到 y i + 1 = y i + k y_{i+1} = y_i + k yi+1=yi+k
这个式子的含义是:当前步的y值等于前一步的y值加上斜率。运用这个思想,算出每一步y的取值,并对y四舍五入得到像素值,即可得到直线段每个像素点的坐标并绘制。
下面是一个简单的举例:绘制直线段(0,0)–(5,2)。

xy四舍五入
000
10+0.40
20.4+0.41
30.8+0.41
41.2+0.42
51.6+0.42

在这里插入图片描述
以上例子仅讨论了k<=1的情况,k>1的情况可同理推出,在代码实现中有讨论,不再举例。

二、C#代码实现

像素点的绘制采用System.Drawing库中Graphics的FillRectangle方法填充单个像素。

        public void DDAline(int x0, int y0, int x1, int y1, Graphics g, Brush brush) //DDA画线法。
        {
            float dx, dy, k;
            dx = x1 - x0;
            dy = y1 - y0;
            if (dx == 0)//斜率不存在情况
            {
                int y;
                for (y = y0; y <= y1; y++)
                {
                    g.FillRectangle(brush, x0, y, 1, 1);
                }
                for (y = y1; y <= y0; y++)
                {
                    g.FillRectangle(brush, x0, y, 1, 1);
                }
            }
            else
            {
                k = dy / dx;
                if (Math.Abs(k) <= 1)//斜率小于1情况。
                {
                    int x;
                    float y = y0;
                    for (x = x0; x <= x1; x++)//x0小于x1情况。
                    {
                        g.FillRectangle(brush, x, (int)Math.Floor(y + 0.5), 1, 1);
                        y += k;
                    }
                    y = y1;
                    for (x = x1; x <= x0; x++)//x1小于x0情况。
                    {
                        g.FillRectangle(brush, x, (int)Math.Floor(y + 0.5), 1, 1);
                        y += k;
                    }
                }
                if (Math.Abs(k) > 1)//斜率大于1情况。
                {
                    float x = x0;
                    int y;
                    for (y = y0; y <= y1; y++)//y0小于y1情况。
                    {
                        g.FillRectangle(brush, (int)Math.Floor(x + 0.5), y, 1, 1);
                        x += 1 / k;
                    }
                    x = x1;
                    for (y = y1; y <= y0; y++)//y1小于y0情况。
                    {
                        g.FillRectangle(brush, (int)Math.Floor(x + 0.5), y, 1, 1);
                        x += 1 / k;
                    }
                }
            }
        }

总结

代码实现过程中,应考虑直线画法的多种情况,避免代码错误。例如考虑斜率不存在的情况,起点x0与终点x1的大小关系。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值