环境:Win10+Visual Studio 2022 Community

在本次实验中需要用到上一篇文章实验内容的代码及环境,详情请见:传送门

目录

一、实验目的

二、实验过程

1.生成直线的DDA算法

2.生成直线的中点算法

3.生成圆的Bresenham算法


一、实验目的

1.熟练掌握生成直线的DDA算法

2.熟练掌握生成直线的中点算法

3.熟练掌握生成圆的Bresenham算法

二、实验过程

1.生成直线的DDA算法

(1)利用已经建立好的DDA直线操作框架,用DDA算法生成直线函数替换系统提供的画线函数g.DrawLine

private void Form1_MouseClick(object sender, MouseEventArgs e)
{Graphics g = CreateGraphics();  //创建图形设备Pen MyPen = new Pen(Color.Red, 1);if (MenuID == 1){if (PressNum == 0)          //第一点,保留{FirstX = e.X;FirstY = e.Y;OldX = e.X;OldY = e.Y;}else                        //第二点,画线{DDALine1(FirstX, FirstY, e.X, e.Y);}PressNum++;if (PressNum >= 2){PressNum = 0;           //画线完毕,清零,为画下一条线做准备}}
}

(2)建立DDALine1函数实现DDA直线算法

        private void DDALine1(int x0, int y0, int x1, int y1){int x, flag;float m, y;Graphics g = CreateGraphics();  //创建图形设备if (x0 == x1 && y0 == y1) return;   //端点重叠,不画。这种情况不可忽略,否则程序有缺陷if (x0 == x1)   //垂直线{if (y0 > y1)    //保证y0为最小{x = y0;y0 = y1;y1 = x;}for (x = y0; x <= y1; x++){g.DrawRectangle(Pens.Red, x1, x, 1, 1); //画点函数,在(x1,x)处画红点}return;}if (y0 == y1)   //水平线{if (x0 > x1){x = x0; x0 = x1; x1 = x;}for (x = x0; x <= x1; x++){g.DrawRectangle(Pens.Red, x, y0, 1, 1);}return;}if (x0 > x1)    //按照算法,(x0,y0)是左端点。如果不满足,就将(x0,y0)、(x1,y1)互换{x = x0; x0 = x1; x1 = x;x = y0; y0 = y1; y1 = x;}flag = 0;   //记录线段种类if (x1 - x0 > y1 - y0 && y1 - y0 > 0) flag = 1; //第一种线段,不做转化工作if (x1 - x0 > y0 - y1 && y0 - y1 > 0)   //第二种线段,转化{flag = 2;y0 = -y0;y1 = -y1;   //关于X轴对称,图形点Y坐标加负号}if (y1 - y0 > x1 - x0)  //第三种线段,关于y=x对称,图形点坐标x,y互换位置{flag = 3;x = x0; x0 = y0; y0 = x;x = x1; x1 = y1; y1 = x;}if (y0 - y1 > x1 - x0)  //第四种线段转化为第一种线段{flag = 4;x = x0; x0 = -y0; y0 = x;x = x1; x1 = -y1; y1 = x;}m = (float)(y1 - y0) / (float)(x1 - x0);for (x = x0, y = (float)y0; x <= x1; x++, y += m){if (flag == 1) g.DrawRectangle(Pens.Red, x, (int)(y + 0.5), 1, 1);if (flag == 2) g.DrawRectangle(Pens.Red, x, -(int)(y + 0.5), 1, 1);if (flag == 3) g.DrawRectangle(Pens.Red, (int)(y + 0.5), x, 1, 1);if (flag == 3) g.DrawRectangle(Pens.Red, (int)(y + 0.5), -x, 1, 1);}}

(3)运行结果

2.生成直线的中点算法

(1)在Form1. cs[设计]页面中,点击、展开菜单项“基本图形生成”,选中子菜单项“中点直线”,并将子菜单项“中点直线”的Name属性值改为"MidLine"

(2)双击“中点直线”菜单项,系统自动建立菜单响应函数MidLine_Click,在该函数中插入如下语句

        private void MidLine_Click(object sender, EventArgs e){MenuID = 2; PressNum = 0;Graphics g = CreateGraphics();  //创建图形设备g.Clear(BackColor1);    //设置背景色}

(3)因为中点直线的操作方法与DDA直线操作方法完全一样,因此只要能够对两者加以区分,就可以借用DDA直线鼠标操作实现程序部分。为此,做如下修改

private void Form1_MouseClick(object sender, MouseEventArgs e){Graphics g = CreateGraphics();  //创建图形设备Pen MyPen = new Pen(Color.Red, 1);if (MenuID == 1 || MenuID == 2){if (PressNum == 0)          //第一点,保留{FirstX = e.X;FirstY = e.Y;OldX = e.X;OldY = e.Y;}else                        //第二点,画线{if (MenuID == 1)DDALine1(FirstX, FirstY, e.X, e.Y);if (MenuID == 2)MidLine1(FirstX, FirstY, e.X, e.Y);}PressNum++;if (PressNum >= 2){PressNum = 0;           //画线完毕,清零,为画下一条线做准备}}}private void Form1_MouseMove(object sender, MouseEventArgs e){Graphics g = CreateGraphics();  //创建图形设备Pen BackPen = new Pen(BackColor1, 1);Pen MyPen = new Pen(ForeColor1, 1);if ((MenuID == 1 || MenuID == 2) && PressNum == 1){if (!(e.X == OldX && e.Y == OldY)){g.DrawLine(BackPen, FirstX, FirstY, OldX, OldY);g.DrawLine(MyPen, FirstX, FirstY, e.X, e.Y);OldX = e.X;OldY = e.Y;}}}

(4)建立MidLine1函数实现中点直线算法

        private void MidLine1(int x0, int y0, int x1, int y1){int x, y, d, flag;Graphics g = CreateGraphics();  //创建图形设备if (x0 == x1 && y0 == y1) return;   //端点重叠,不画if (x0 == x1)   //垂直线{if (y0 > y1){x = y0;y0 = y1;y1 = x;}for (y = y0; y <= y1; y++){g.DrawRectangle(Pens.Red, x1, y, 1, 1); //画点函数,在(x1,y)处画红点}return;}if (y0 == y1)   //水平线{if (x0 > x1){x = x0; x0 = x1; x1 = x;}for (x = x0; x <= x1; x++){g.DrawRectangle(Pens.Red, x, y0, 1, 1);//画点函数,在(x,y0)处画红点}return;}if (x0 > x1)    //起点(x0,y0)是左端点,如果不满足,就将(x0,y0)、(x1,y1)互换{x = x0; x0 = x1; x1 = x;x = y0; y0 = y1; y1 = x;}flag = 0;   //直线类别标记if (x1 - x0 > y1 - y0 && y1 - y0 > 0) flag = 1; //第一种线段,不做转化工作if (x1 - x0 > y0 - y1 && y0 - y1 > 0)   //第二种线段转化为第一种线段{flag = 2;y0 = -y0;y1 = -y1;}if (y1 - y0 > x1 - x0)  //第三种线段转化为第一种线段{flag = 3;x = x0; x0 = y0; y0 = x;x = x1; x1 = y1; y1 = x;}if (y0 - y1 > x1 - x0)  //第四种线段转化为第一种线段{flag = 4;x = x0; x0 = -y0; y0 = x;x = x1; x1 = -y1; y1 = x;}x = x0; y = y0; d = (x1 - x0) - 2 * (y1 - y0);while (x < x1 + 1){if (flag == 1) g.DrawRectangle(Pens.Red, x, y, 1, 1);if (flag == 2) g.DrawRectangle(Pens.Red, x, -y, 1, 1);if (flag == 3) g.DrawRectangle(Pens.Red, y, x, 1, 1);if (flag == 3) g.DrawRectangle(Pens.Red, y, -x, 1, 1);x++;if (d > 0){d = d - 2 * (y1 - y0);}else{y++;d = d - 2 * ((y1 - y0) - (x1 - x0));}}}

(5)运行结果

3.生成圆的Bresenham算法

(1)在“基本图形生成”菜单项下选中子菜单“Bresenham圆”,将子菜单的Name属性值改为“BresenhamCircle”

(2)双击子菜单项“Bresenham圆”,在系统生成的菜单响应函数BresenhamCircle_Click中增添如下内容

        private void BresenhamCircle_Click(object sender, EventArgs e){MenuID = 5; PressNum = 0;Graphics g = CreateGraphics();  //创建图形设备g.Clear(BackColor1);            //设置背景色}

(3)和直线生成一样,这里的响应函数只是做一个基本图形生成的类型标识,真正的图形生成操作在鼠标操作中完成。鼠标画圆的操作方式确定为:先用鼠标确定圆心,再用鼠标确定圆上任意一点。在鼠标点击响应函数中插人如下语句

        private void Form1_MouseClick(object sender, MouseEventArgs e){Graphics g = CreateGraphics();  //创建图形设备Pen MyPen = new Pen(Color.Red, 1);if (MenuID == 1 || MenuID == 2){if (PressNum == 0)          //第一点,保留{FirstX = e.X;FirstY = e.Y;OldX = e.X;OldY = e.Y;}else                        //第二点,画线{if (MenuID == 1)DDALine1(FirstX, FirstY, e.X, e.Y);if (MenuID == 2)MidLine1(FirstX, FirstY, e.X, e.Y);}PressNum++;if (PressNum >= 2){PressNum = 0;           //画线完毕,清零,为画下一条线做准备}}if (MenuID == 5) //画圆部分{if (PressNum == 0)    //圆心,保留{FirstX = e.X;FirstY = e.Y;}else //圆上任意一点,确定半径{if (FirstX == e.X && FirstY == e.Y) return;BresenhamCircle1(FirstX, FirstY, e.X, e.Y);}PressNum++;if (PressNum >= 2){PressNum = 0;           //画圆完毕,清零,为画下一个圆做准备}}}

(4)在鼠标移动响应函数中插入如下语句

        private void Form1_MouseMove(object sender, MouseEventArgs e){Graphics g = CreateGraphics();  //创建图形设备Pen BackPen = new Pen(BackColor1, 1);Pen MyPen = new Pen(ForeColor1, 1);if ((MenuID == 1 || MenuID == 2) && PressNum == 1){if (!(e.X == OldX && e.Y == OldY)){g.DrawLine(BackPen, FirstX, FirstY, OldX, OldY);g.DrawLine(MyPen, FirstX, FirstY, e.X, e.Y);OldX = e.X;OldY = e.Y;}}if (MenuID == 5 && PressNum == 1){if (!(e.X == OldX && e.Y == OldY)){//求圆半径double r = Math.Sqrt((FirstX - OldX) * (FirstX - OldX) + (FirstY - OldY) * (FirstY - OldY));int r1 = (int)(r + 0.5);    //取整g.DrawEllipse(BackPen, FirstX - r1, FirstY - r1, 2 * r1, 2 * r1);//擦除旧圆//求圆半径r = Math.Sqrt((FirstX - e.X) * (FirstX - e.X) + (FirstY - e.Y) * (FirstY - e.Y));r1 = (int)(r + 0.5);     //取整g.DrawEllipse(MyPen, FirstX - r1, FirstY - r1, 2 * r1, 2 * r1);}}}

(5)g.DrawEllipse函数是系统提供的画椭圆函数,这里借助它,通过画一个长短轴相等的椭圆,实现画圆的橡皮筋。BresenhamCircle1函数是真正用圆的算法实现画圆的函数,还没建立。在程序Form1.cs程序中建立BresenhamCircle1函数如下

        private void BresenhamCircle1(int x0, int y0, int x1, int y1){int r, d, x, y;Graphics g = CreateGraphics();  //创建图形设备r = (int)(Math.Sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)) + 0.5);x = 0; y = r; d = 3 - 2 * r;while (x < y || x == y){g.DrawRectangle(Pens.Blue, x + x0, y + y0, 1, 1);g.DrawRectangle(Pens.Red, -x + x0, y + y0, 1, 1);g.DrawRectangle(Pens.Green, x + x0, -y + y0, 1, 1);g.DrawRectangle(Pens.Yellow, -x + x0, -y + y0, 1, 1);g.DrawRectangle(Pens.Black, y + x0, x + y0, 1, 1);g.DrawRectangle(Pens.Red, -y + x0, x + y0, 1, 1);g.DrawRectangle(Pens.Red, y + x0, -x + y0, 1, 1);g.DrawRectangle(Pens.Red, -y + x0, -x + y0, 1, 1);x++;if (d < 0 || d == 0){d = d + 4 * x + 6;}else{y = y - 1;d = d + 4 * (x - y) + 10;}}}

(6)运行结果

计算机图形学实习教程之基本图形的生成(直线DDA算法,直线中点算法,Bresenham画圆算法),利用C#实现,附源码相关推荐

  1. 【计算机图形学】小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解

    小白谈计算机图形学(二)画圆篇之中点画圆法,Bresenham画圆算法,椭圆实操,线型处理详解 引言 如何画圆 基本思想 中点画圆法 中点画圆基本思路 中点画圆改进 Bresenham画圆算法 Bre ...

  2. 中点Bresenham画圆算法|MFC|计算机图形学

    中点Bresenham画圆算法|MFC|计算机图形学 Bresenham中点画圆算法 计算机图形学-基本图元的生成-圆 基于学习直线的生成算法后,又展开了圆.椭圆的讲解: 此次试验是简单的MFC应用, ...

  3. 【计算机图形学】中点画圆算法和Bresenham画圆算法

    在平面解析几何中,圆的方程可以描述为(x – x0)2 + (y – y0)2 = R2,其中(x0, y0)是圆心坐标,R是圆的半径,特别的,当(x0, y0)就是坐标中心点时,圆方程可以简化为x2 ...

  4. 计算机图形学(1)基本图形算法

    计算机图形学--基本图形算法 光栅图形中点的表示 屏幕坐标系在左上角 地址=(Xmax-Xmin)[每行像素点数]*(Y-Ymin)[行数]+(X-Xmin)[行中位置]+基地址 直线扫描转换算法 假 ...

  5. 计算机图形学孔令德基础知识,计算机图形学基础教程孔令德答案

    计算机图形学基础教程孔令德答案 [篇一:大学计算机图形学课程设] 息科学与工程学院课程设计任务书 题目: 小组成员:巴春华.焦国栋 成员学号:专业班级:计算机科学与技术.2009级本2班课程: 计算机 ...

  6. 计算机图形学结课论文,计算机图形学基础教程结课论文

    计算机图形学是研究如何在计算机中生成.显示和处理图形的一门学科.计算机图形学具有较高的实用价值.下面是学习啦小编给大家推荐的计算机图形学基础教程结课论文,希望大家喜欢! 计算机图形学基础教程结课论文篇 ...

  7. 计算机图形学基础教程代码,计算机图形学基础教程

    <计算机图形学基础教程>由会员分享,可在线阅读,更多相关<计算机图形学基础教程(19页珍藏版)>请在人人文库网上搜索. 1.第一章 1. 计算机图形学的主要研究内容是什么? 答 ...

  8. 计算机图形学二维图形基本变换实验原理,计算机图形学实验:二维图形变换.docx...

    计算机图形学实验:二维图形变换.docx (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实验三 二维图形变换一.实验任务1. 通 ...

  9. 计算机图形学 实验7 《复杂图形绘制-Bezier曲线与Hermite曲线》

    计算机图形学 实验7 <复杂图形绘制-Bezier曲线与Hermite曲线> 一.实验目的 学习样条曲线的绘制. 二.实验内容 1.绘制Bezier曲线: 2.绘制Hermite曲线. 三 ...

最新文章

  1. 送餐送货机器人、自动驾驶车、扫地机器人,再也不用担心撞上玻璃橱窗了丨CVPR2020...
  2. python 判断变量是否是 None 的三种写法
  3. 手机卫士09_应用程序四种查看_ListView小标题_进程管理
  4. 计算机网络(二十三)-网络层-概述与数据交换方式
  5. break和continue的方法(break 直接跳出循环)与 (continue本次忽略,但之后的继续)
  6. Windows8中离线安装.Net 3.5的方法
  7. 安卓Notification通知栏全解
  8. 用OFFICE 2007发送的文章
  9. 在 Silverlight 中管理动态内容交付,第 1 部分
  10. Mybatis多表新增
  11. visio的替代工具 - draw.io
  12. java 控制台 全屏_Java全屏模式与退出全屏:
  13. 在JS数组特定索引处指定位置插入或修改元素的技巧
  14. 【论文阅读】Phase-aware speech enhancement with deep complex U-net
  15. C语言中求余运算符的注意事项
  16. Python Web 框架-Django day05
  17. 苹果故意降低旧手机性能 曾经创新巨擘为何沦落风尘?
  18. 海报创意|十月的节日热点:国庆、重阳和万圣节
  19. 哈啰出行Java面试
  20. 用python进行图片素描

热门文章

  1. AVAGO MegaRAID SAS 9361-8i配置IPMI以及JBOD直通模式
  2. Sandstorm 建设者亮点——2023 年 2 月
  3. 关于WiderPerson数据说明(使用后笔记)
  4. 郑州高新区php平均收入,郑州公布各区平均工资,你又拖后腿了?
  5. Python基础——格式化输出
  6. char * name字符串使用
  7. MySQL在线升级方案
  8. 计算机原理学习指导第3版,计算机组成原理学习指导与习题解析(第3版)(21世纪大学本科计算机...
  9. 在RHEL5下安装腾迅QQ(VMware中进行)
  10. 【汇正财经】国家股是什么意思?什么是国家股?