[计算机图形学] 基于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,如需转载请自行联系原作者

相关文章
|
1月前
|
开发框架 算法 搜索推荐
C# .NET面试系列九:常见的算法
#### 1. 求质数 ```c# // 判断一个数是否为质数的方法 public static bool IsPrime(int number) { if (number < 2) { return false; } for (int i = 2; i <= Math.Sqrt(number); i++) { if (number % i == 0) { return false; } } return true; } class Progr
58 1
|
4月前
|
搜索推荐 算法 C#
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
【Unity 3D】C#中冒泡排序、选择排序、插入排序等算法的详解(附源码 超详细)
47 1
|
4月前
|
算法 图形学
【头歌 计算机图形学 练习】多边形填充v1.0 (第1关:扫描线填充算法(活动边表AET法) 第2关:边缘填充法 第3关:区域四连通种子填充算法 第4关:区域扫描线种子填充算法)
【头歌 计算机图形学 练习】多边形填充v1.0 (第1关:扫描线填充算法(活动边表AET法) 第2关:边缘填充法 第3关:区域四连通种子填充算法 第4关:区域扫描线种子填充算法)
175 0
|
1月前
|
设计模式 C#
36.c#:如何设置MDL窗口
36.c#:如何设置MDL窗口
15 1
|
1月前
|
C# 开发者
35.c#:winform窗口
35.c#:winform窗口
13 1
|
1月前
|
搜索推荐 C#
C#实现选择排序算法
C#实现选择排序算法
17 2
|
1月前
|
搜索推荐 C#
C#实现冒泡排序算法
C#实现冒泡排序算法
19 0
|
2月前
|
算法 数据可视化 vr&ar
【图形学】探秘图形学奥秘:DDA与Bresenham算法的解密与实战
【图形学】探秘图形学奥秘:DDA与Bresenham算法的解密与实战
43 0
|
3月前
|
算法 C#
C# .Net Core bytes转换为GB/MB/KB 算法
C# .Net Core bytes转换为GB/MB/KB 算法
42 0
|
4月前
|
存储 算法 数据处理
C# | 上位机开发新手指南(十一)压缩算法
流式压缩 流式压缩是一种能够实时处理数据流的压缩方式,例如音频、视频等实时传输的数据。 通过流式压缩算法,我们可以边读取边压缩数据,并能够随时输出已压缩的数据,以确保数据的实时性和减少存储和传输所需的带宽。 块压缩 块压缩则是将数据划分为固定大小的块,在每个块内进行独立的压缩处理。块压缩通常适用于文件、存储、传输等离线数据处理场景。 字典压缩 字典压缩是一种基于字典的压缩算法,通过建立一个字典来存储一组重复出现的字符串,并将这些字符串替换成字典中相应的索引,从而减少数据的存储和传输。字典压缩算法可以更好地处理数据中的重复模式,因为它们可以通过建立字典来存储和恢复重复出现的字符串。
46 0
C# | 上位机开发新手指南(十一)压缩算法