[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

简介:


 

 

 

一、首先说明: 

  • 这是啥? —— 这是利用C#FORM写的一个用来演示计算机图形学中 ①Bresenham直线扫描算法(即:连点成线);②种子填充法(即:填充多边形);③扫描线填充法
  • 有啥用? ——  无论是连点成线还是区域填充在高级编程中基本上都提供很高效的库函数来调用。这里拿出这些算法一方面有利于大家理解那些封装的函数底层是实现;另一方面是方便嵌入式TFT屏幕底层驱动开发时借鉴的。
  • 是啥样? ——  如下面的操作,不言而喻。

     

二、进入正题:

 2-1、直线的扫描转换

    图形的扫描转换实质就是在光栅等数字设备上确定一个最佳逼近于图形的像素集的过程。 

   

    对于直线扫描转换其实就是确定最佳逼近于该直线的一组像素,然后按照扫描线的顺序对这些像素进行写操作。三种比较常用的算法是:①数值微分法(DDA);②中点画线法;③Bresenham算法。这里主要讲第三个算法,因为这个效率高且易于硬件实现。

    Bresenham算法:由于显示直线的象素点只能取整数值坐标,可以假设直线上第i个象素点坐标为(xi,yi) ,它是直线上点(xi,yi)的最佳近似,并且xi=xi(假设m<1),如下图所示。那么,直线上下一个象素点的可能位置是(xi+1,yi) 或(xi+1,yi+1)。

    

    而实际的点为红色的点,可以计算可能点与实际点的偏差的差,即:d1-d2=2m(xi+1)-2yi+ 2b-1。这样根据这个差就能判断下一点的坐标,然后一直向前推进就能求出所有的点。此外由于考虑硬件对浮点数处理的速度要比对整数处理的速度慢许多的情况,在该算法里会对该式子做一些变换(其实就是放大使其变为整数,同时保证下一点求法正确)。由于网上资料很多,这里就不细讲了~

    Bresenham算法伪代码:[条件:0<=m<=1且x1<x2]

    ①输入线段的两个端点坐标和画线颜色:x1,y1,x2,y2,color;
②设置象素坐标初值:x=x1,y=y1;
③设置初始误差判别值:p=2·Δy-Δx;
④分别计算:Δx=x2-x1、Δy=y2-y1;
⑤循环实现直线的生成:

复制代码
 1 for(x=x1;x<=x2;x++)
 2 { 
 3     putpixel(x,y,color);
 4     if(p>=0)
 5     { 
 6         y=y+1;
 7         p=p+2*(Δy-Δx);
 8     }
 9     else
10     { 
11         p=p+2*Δy;
12     }
13 }
复制代码

  显然,上述算法是带有一定限制条件的,下面我们将其推广到所有斜率的情况,实现各种线的绘制。容易证明:当线段处于①、④、⑧、⑤区域时,以|Δx|和|Δy|代替前面公式中的Δx和Δy;当线段处于②、③、⑥、⑦区域时,把|Δx|和|Δy|对换。下面是工程中用于连点成线的基于Bresenham算法的函数:

  

复制代码
 1 /// <summary>
 2 /// Bresenham画线算法,给出两个点a,b
 3 /// </summary>
 4 /// PS:这里XiangSu是光栅的最小距离,因为我是在高分辨率的窗口中模拟低分辨率效果,
 5 /// 所以用这个XiangSu来控制模拟的光栅最小单元格的边的大小,实际运用中XiangSu=1
 6 /// <param name="a"></param>
 7 /// <param name="b"></param>
 8 void Bresenhamline(Point a, Point b)
 9 {
10     int x, y, dx, dy, s1, s2, p, temp, interchange, i;
11     x = a.X;
12     y = a.Y;
13     dx = Math.Abs(b.X - a.X);
14     dy = Math.Abs(b.Y - a.Y);
15     if (b.X > a.X)
16         s1 = XiangSu;
17     else
18         s1 = -XiangSu;
19     if (b.Y > a.Y)
20         s2 = XiangSu;
21     else
22         s2 = -XiangSu;
23     if (dy > dx)
24     {
25         temp = dx;
26         dx = dy;
27         dy = temp;
28         interchange = 1;
29     }
30     else
31         interchange = 0;
32     p = 2 * dy - dx;
33     for (i = 1; i <= dx; i += XiangSu)
34     {
35         tempp.X = x;
36         tempp.Y = y;
37         tempP.Add(tempp);
38         Vram[x + y * 600] = true;//把该片内存置为边界标记
39         if (p >= 0)
40         {
41             if (interchange == 0)
42                 y = y + s2;
43             else
44                 x = x + s1;
45             p = p - 2 * dx;
46         }
47         if (interchange == 0)
48             x = x + s1;
49         else
50             y = y + s2;
51         p = p + 2 * dy;
52     }
53 }
复制代码

 

由于版面受限,请链接到第二节,更加精彩,哈哈:http://www.cnblogs.com/zjutlitao/p/4117223.html

两篇链接:

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(一)

[计算机图形学] 基于C#窗口的Bresenham直线扫描算法、种子填充法、扫描线填充法模拟软件设计(二) 

 



本文转自beautifulzzzz博客园博客,原文链接:http://www.cnblogs.com/zjutlitao/p/4116783.html,如需转载请自行联系原作者

相关文章
|
4月前
|
Web App开发 数据采集 C#
解决Firefox代理身份验证弹出窗口问题:C#和Selenium实战指南
本文是一份实战指南,主要介绍了在使用Selenium和C#进行网页抓取时,如何设置代理服务器的身份验证以避免自动化流程中断。文章首先列出了所需的开发环境和工具,然后通过C#代码示例详细展示了如何在Firefox浏览器中设置代理IP、端口、用户名、密码以及UserAgent和Cookies。代码中包含了自动处理代理身份验证弹出窗口的配置,以及如何添加Cookies的方法。最后,文章强调了结合C#和Selenium可以提高网页抓取任务的稳定性和效率。
解决Firefox代理身份验证弹出窗口问题:C#和Selenium实战指南
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
26天前
|
存储 算法 C#
C#哈希查找算法
C#哈希查找算法
|
26天前
|
算法 C# 索引
C#二分查找算法
C#二分查找算法
|
1月前
|
机器学习/深度学习 算法 数据挖掘
使用C# 实现期望最大化算法
使用C# 实现期望最大化算法
45 0
|
2月前
|
存储 算法 C#
C#二叉搜索树算法
C#二叉搜索树算法
|
4月前
|
数据采集 Web App开发 JavaScript
快速参考:用C# Selenium实现浏览器窗口缩放的步骤
在C#结合Selenium的网络爬虫应用中,掌握浏览器窗口缩放、代理IP、cookie与user-agent设置至关重要。本文详述了如何配置代理(如亿牛云加强版),自定义用户代理,启动ChromeDriver,并访问目标网站如抖音。通过执行JavaScript代码实现页面缩放至75%,并添加cookie增强匿名性。此策略有效规避反爬机制,提升数据抓取的准确度与范围。代码示例展示了整个流程,确保爬虫操作的灵活性与高效性。
111 3
|
3月前
|
算法
空间点与直线距离算法
空间点与直线距离算法
53 0
|
3月前
|
算法 C++
空间直线与球面相交算法
空间直线与球面相交算法
28 0
|
3月前
|
算法 Java 索引
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
36 0