[计算机图形学] 基于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月前
|
存储 算法 缓存
高并发架构设计三大利器:缓存、限流和降级问题之滑动窗口算法的原理是什么
高并发架构设计三大利器:缓存、限流和降级问题之滑动窗口算法的原理是什么
|
4月前
|
算法 API 缓存
高并发架构设计三大利器:缓存、限流和降级问题之固定窗口限流算法的原理是什么
高并发架构设计三大利器:缓存、限流和降级问题之固定窗口限流算法的原理是什么
|
4月前
|
算法 Java
详解 Java 限流接口实现问题之理解固定窗口限流算法的窗口边界问题如何解决
详解 Java 限流接口实现问题之理解固定窗口限流算法的窗口边界问题如何解决
|
4月前
|
算法 Java
详解 Java 限流接口实现问题之固定窗口限流算法的实现原理是什么
详解 Java 限流接口实现问题之固定窗口限流算法的实现原理是什么
|
6月前
|
算法 图形学
【计算机图形学】实验一 DDA算法、Bresenham算法
【计算机图形学】实验一 DDA算法、Bresenham算法
208 3
|
6月前
|
算法 图形学
【计算机图形学】实验三 用Cohen-Sutherland裁剪算法实现直线段裁剪
【计算机图形学】实验三 用Cohen-Sutherland裁剪算法实现直线段裁剪
442 2
|
6月前
|
存储 算法 图形学
【计算机图形学】实验二 用扫描线算法实现多边形填充
【计算机图形学】实验二 用扫描线算法实现多边形填充
202 2
|
6月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
192 3
|
14天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
29 3
|
1月前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。
101 0