计算机图形学直线算法(DDA,中点画线 ,Bresenham.VS2019 )

功能:由鼠标单击给定初末点位置作出相应直线。

1,打开VS2019 选择新建项目 Windows 窗体应用(.NET framework)
在大这里插入图片描述打开
2,此处项目名称命名为“Computer_Graphics”,项目建立后出现如下视图在这里插入图片描述
3,在左侧工具箱选中“MenuStrip”将其拖入“Form1”窗体中
在这里插入图片描述
键入想要设计的功能,这里设计了如图所示三种画直线的算法
在这里插入图片描述
窗体设计完成,开始写代码。现在代码区插入如下代码

        Color BackColor1 = Color.White;              //指定窗体背景色
        Color ForeColor1 = Color.Black;              //指定线的颜色
        public int MenuID = 0, PressNum = 0;         //pressnum = 1时画直线
        public Point Firstpoint = new Point(0, 0);   //定义第一个点
        public Point Secondpoint = new Point(0, 0);  //定义第二个点
        public int Ways = 1;                         //记录在窗体中的操作

在这里插入图片描述
由于直线初末位置由鼠标单击窗体给出,所以要先定义窗体的鼠标单击响应函数。先单击选中窗体,在界面右下角找到属性框,点击“事件”(小闪电图标)在下面给出的事件中找到“MouseClick”,双击进入代码窗口在这里插入图片描述进入代码区后,键入如下代码

            Graphics g = CreateGraphics();
            Pen Mypen = new Pen(Color.Red, 1);
            if (MenuID == 1)
            {
                if (PressNum == 0)
                {
                    Firstpoint.X = e.X; Firstpoint.Y = e.Y;
                    Secondpoint.X = e.X; Secondpoint.Y = e.Y;
                }
                else
                {
                    if (Ways == 1)
                    {
                        DDLline(Firstpoint.X, Firstpoint.Y, Secondpoint.X, Secondpoint.Y);//------调用DDA画直线
                    }
                    if (Ways == 2)
                    {
                        Midpoint(Firstpoint.X, Firstpoint.Y, Secondpoint.X, Secondpoint.Y);//------调用中点画线法
                    }
                    if (Ways == 3)
                    {
                        Bresenham(Firstpoint.X, Firstpoint.Y, Secondpoint.X, Secondpoint.Y);//-----调用bresenham算法
                    }
                }
                PressNum++;
                if (PressNum >= 2)
                    PressNum = 0;
            }

在这里插入图片描述
此时还需要一个鼠标移动函数记录鼠标在窗体中的移动位置,同样选中窗体,在界面右下角找到属性框,点击“事件”(小闪电图标)在下面给出的事件中找到“MouseMove”,双击进入代码窗口
在这里插入图片描述
进入代码区后键入如下代码

            Graphics g = CreateGraphics();
            Pen Backpen = new Pen(BackColor1, 1);
            Pen Mypen = new Pen(ForeColor1, 1);
            if (MenuID == 1 && PressNum == 1)
            {
                if (!(e.X == Secondpoint.X && e.Y == Secondpoint.Y))
                {
                    g.DrawLine(Backpen, Firstpoint.X, Firstpoint.Y, Secondpoint.X, Secondpoint.Y);//底层白线,可不要
                    g.DrawLine(Mypen, Firstpoint.X, Firstpoint.Y, e.X, e.Y);//中间线黑线,可不要
                    Secondpoint.X = e.X;
                    Secondpoint.Y = e.Y;
                }
            }

在这里插入图片描述

接下来完善功能代码,回到“Form1” 窗口,找到之前设计的“DDA画线法”,双击进入代码区域,键入如下代码

            Ways = 1;
            MenuID = 1;插入代码片

在这里插入图片描述
同样的方式创立“中点画线法”,“Bresenham画线法”单击响应函数
在这里插入图片描述

划重点:三种直线算法函数的设计
1.DDA画线法
代码区键入如下代码


            Graphics g = CreateGraphics();
            Pen b = new Pen(Color.Red, 1);
            if (x0 == x1 && y0 == y1)
                return;
            double x, y;                         //记录即时坐标
            double dx, dy;                       //记录起点和终点的坐标差值
            double delta_x, delta_y;             //记录划线过程中的坐标增量
            double steps;                        //记录步长
            dx = x1 - x0;
            dy = y1 - y0;
            if (Math.Abs(dx) > Math.Abs(dy))     //比较横纵坐标增量的大小
                steps = dx;
            else
                steps = dy;                     //确保每次的增量不超过一个单位长度
            x = x0;
            y = y0;                             //记录画线起点
            delta_x = (double)(dx * 1.0) / Math.Abs(steps);
            delta_y = (double)(dy * 1.0) / Math.Abs(steps);   //计算相邻两个点的增量
            for (int i = 0; i < Math.Abs(steps); i++)
            {
                x = x + delta_x;
                y = y + delta_y;
                g.DrawRectangle(b, (int)x, (int)(y + 0.5), 1, 1);

放个图
在这里插入图片描述
2,中点画线法
代码区键入如下代码

private void Midpoint(int x0, int y0, int x1, int y1)//------------中点画线法
        {
            Graphics g = CreateGraphics();
            Pen p = new Pen(Color.Green, 1);
            if (x0 == x1 && y0 == y1)
                return;
            double a = y0 - y1;
            double b = x1 - x0;
            double c = x0 * y1 - x1 * y0;
            double x, y, k, d;
            k = -a / b;
            //--------------------------------------
            if (k > 0 && k < 1)
            {
                if (x1 > x0)
                {
                    y = y0;
                    for (x = x0; x < x1;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d < 0)
                        { x++; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { x++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
                if (x1 < x0)
                {
                    y = y1;
                    for (x = x1; x < x0;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d > 0)
                        { x++; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { x++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
            }
            //-------------------------
            if (k >= 1)
            {
                if (y1 > y0)
                {
                    x = x0;
                    for (y = y0; y < y1;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d > 0)
                        { x++; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
                if (y1 < y0)
                {
                    x = x1;
                    for (y = y1; y < y0;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d < 0)
                        { x++; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
            }
            //------------------------------------
            if (k <= 0 && k > -1)
            {
                if (x1 > x0)
                {
                    y = y1;
                    for (x = x1; x > x0;)
                    {
                        d = a * (x - 1) + b * (y + 0.5) + c;
                        if (d < 0)
                        { x--; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { x--; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                    }
                }
                if (x0 > x1)
                {
                    y = y0;
                    for (x = x0; x > x1;)
                    {
                        d = a * (x - 1) + b * (y + 0.5) + c;
                        if (d > 0)
                        { x--; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { x--; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                    }
                }
            }
            //---------------------------------------
            if (k <= -1)
            {
                if (y1 > y0)
                {
                    x = x0;
                    for (y = y0; y < y1;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d < 0)
                        { x--; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
                if (y1 < y0)
                {
                    x = x1;
                    for (y = y1; y < y0;)
                    {
                        d = a * (x + 1) + b * (y + 0.5) + c;
                        if (d > 0)
                        { x--; y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }
                        else
                        { y++; g.DrawRectangle(p, (int)x, (int)y, 1, 1); }

                    }
                }
            }
            //---------------------------------------
            if (x1 == x0)
            {
                x = x0;
                if (y1 < y0)
                {
                    y = y0;
                    y0 = y1;
                    y1 = (int)y;
                    x = x1;
                }
                for (y = y0; y <= y1; y++)
                {
                    g.DrawRectangle(p, (int)x, (int)y, 1, 1);
                }
            }
        }

3,Bresenham画线法
代码区键入如下代码

private void Bresenham(int x0, int y0, int x1, int y1)//--------------------------Bresenham算法
        {
            Graphics g = CreateGraphics();
            Pen p = new Pen(Color.Blue, 1);
            if (x0 == x1 && y0 == y1)
                return;
            double dx = x1 - x0;
            double dy = y1 - y0;
            double k = dy / dx;
            double e = -0.5;
            int x = x0;
            int y = y0;
            int i;

            if (k > 0 && k <= 1)
            {
                if (x1 < x0)
                {
                    x = x1;
                    y = y1;
                    dx = x0 - x1;
                    dy = y0 - y1;
                }
                for (i = 0; i <= dx; i++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                    x = x + 1;
                    e = e + k;
                    if (e >= 0)
                    {
                        y++;
                        e = e - 1;
                    }
                }
            }
            //-----------------------------------------
            if (k > 1)
            {
                if (y1 < y0)
                {
                    x = x1;
                    y = y1;
                    dx = x0 - x1;
                    dy = y0 - y1;
                }
                for (i = 0; i <= dy; i++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                    y = y + 1;
                    e = e + 1 / k;
                    if (e >= 0)
                    {
                        x++;
                        e = e - 1;
                    }
                }
            }
            //--------------------------------------------
            if (k <= -1)
            {
                if (y1 < y0)
                {
                    x = x1;
                    y = y1;
                    dx = x0 - x1;
                    dy = y0 - y1;
                }
                for (i = 0; i <= dy; i++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                    y = y + 1;
                    e = e - 1 / k;
                    if (e >= 0)
                    {
                        x--;
                        e = e - 1;
                    }
                }
            }
            //--------------------------------------
            if (k < 0 && k > -1)
            {
                if (x1 < x0)
                {
                    x = x1;
                    y = y1;
                    dx = x0 - x1;
                    dy = y0 - y1;
                }
                for (i = 0; i <= dx; i++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                    x = x + 1;
                    e = e - k;
                    if (e >= 0)
                    {
                        y--;
                        e = e - 1;
                    }
                }
            }
            //---------------------------------------
            if (x1 == x0)
            {
                if (y1 < y0)
                {
                    y = y0;
                    y0 = y1;
                    y1 = y;
                    x = x1;
                }
                for (y = y0; y <= y1; y++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                }
            }
            //--------------------------

            if (k == 0)
            {
                if (x1 < x0)
                {
                    x = x0;
                    x0 = x1;
                    x1 = x;
                    y = y1;
                }
                for (x = x0; x < x1; x++)
                {
                    g.DrawRectangle(p, x, y, 1, 1);
                }
            }
        }

画直线功能大功告成
运行结果
在这里插入图片描述
设计一个清除画线功能,点击清除进入代码区
键入如下代码

            Graphics g = CreateGraphics();
            g.Clear(Color.White);
            MenuID = 0;

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值