吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 2632|回复: 7

[C#] C# 写Mandelbrot集合,数学之美,最漂亮的分形制作全过程

[复制链接]
大官人 发表于 2014-11-7 14:45 | 显示全部楼层 |阅读模式

本帖最后由 大官人 于 2014-11-7 16:21 编辑

Mandelbrot集合不介绍 详见百度百科

点我查看

现在在你的VS里面新建一个控制台程序:
代码如下

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;

  6. namespace Mandelbrot1
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             double realCoord, imagCoord;
  13.             double realTemp, imagTemp, realTemp2, arg;
  14.             int iterations;
  15.             for (imagCoord = 1.2; imagCoord >= -1.2; imagCoord -= 0.05)
  16.             {
  17.                 for (realCoord = -0.6; realCoord <= 1.77; realCoord += 0.03)
  18.                 {
  19.                     iterations = 0;
  20.                     realTemp = realCoord;
  21.                     imagTemp = imagCoord;
  22.                     arg = (realCoord * realCoord) + (imagCoord * imagCoord);
  23.                     while ((arg < 4) && (iterations < 40))
  24.                     {
  25.                         realTemp2 = (realTemp * realTemp) - (imagTemp * imagTemp) - realCoord;
  26.                         imagTemp = (2 * realTemp * imagTemp) - imagCoord;
  27.                         realTemp = realTemp2;
  28.                         arg = (realTemp * realTemp) + (imagTemp * imagTemp);
  29.                         iterations += 1;
  30.                     }
  31.                     switch (iterations % 4)
  32.                     {
  33.                         case 0:
  34.                             Console.Write("。");
  35.                             break;
  36.                         case 1:
  37.                             Console.Write("S");
  38.                             break;
  39.                         case 2:
  40.                             Console.Write("B");
  41.                             break;
  42.                         case 3:
  43.                             Console.Write("草");
  44.                             break;
  45.                     }
  46.                 }
  47.                 Console.Write("\n");
  48.             }
  49.             Console.ReadKey();
  50.         }
  51.     }
  52. }
复制代码
在Mandelbrot图像中的每个位置都可以用N = x+y*i的一个复数表示,实数部分是x,虚数部分是y(啥叫复数虚数俺也不懂反正跟咱写代码没关系 记着这个表达式就行)i是-1的平方根。图像中各个位置的x和y的左边对应于复数的x和y部分。(这句才是重点!)

图像中每个位置用参数N来表示,它的值为x*x+y*y的平方根。如果这个值大于或者等于2,那么这个数字对应的位置值是0.如果参数N的值小于2,就把N的值改为N*N-N,即:N=(x*x-y*y-x)+(2*x*y-y)*i),并再次测试这个新N值。如果这个值大于或者等于2,则这个数字对应的位置值是1.这个过程将一直继续下去,直到给图像中的位置赋予一个值,或者迭代执行的次数超过制定的次数为止。
根据给图像中的每个点赋予的值,在图形幻甲下,屏幕 上会显示某种颜色的像素。但是,咱们在控制台文本环境,所以屏幕上显示的是字符。


看看这些代码,以及其中的循环,首先声明计算过程中需要的变量:double realCood, imagCoord;
double realTemp,imagTemp,realTemp2,arg;
int iterations;
其中 realCood和imagCood是Mandelbrot集合的位置参数 具体怎么计算咱不管 咱只讨论怎么实现

然后几个Temp参数 就是临时信息 指的是存储计算过程中的几个临时信息的变量,然后iterations呢是记录N(arg)大于或者等于2之前的迭代次数。

接着是两个for循环,
for (imagCood = 1.2;  imagCood >= 1.2; imagCood -= 0.05)
{
     for(realCood = -0.6; realCood <= 1.77; realCood += 0.03)
          {

          }
}
上面是两个for循环

咱们来看看
首先了解一下数学运算符 -= 和+=
a -=  b
这个的意思就是a被赋予a与b的差
a += b
这个的意思呢 就是a被赋予a与b的和

这里说一下++a 和a++的区别为此我这个菜鸟也纠结了好一阵子

++a和a++,都是个表达式,最后的结果就取决于是先加,还是后加,如果是先加,那么最后的表达式的结果就是a的值加1,如果是后加的话,则表达式的值就是原来a的值;而无论是先加,还是后加,a的值计算后一定会加1。
比如:
如果a=1,b=a++,运算完b=1,a=2
如果a=1,b=++a,运算完b=2,a=2



for循环呢
王大大已经讲得很明白了
详见
C#初级开发原创教程第八课 循环结构(二)

不过这里还要补充一下
比如:
int i;
for (i = 1; i <= 10; ++i )
{
   Console.WriteLine("{0}",i);
}
Console.ReadKey();
执行结果如下

QQ截图20141107152115.png
计数器变量是一个整数i,他的初始值是1,在每次循环的后面递增1.在每次循环过程中,把i的值写到控制台上。
  主意:当i的值为11时,将执行循环后面的代码。这是因为在i等于10的循环末尾,i会递增为11.这是在测试条件i<=10之前发生的,此时循环结束。与while循环一样,在第一次执行前,只在条件判定为ture时才执行for循环,所以可能根本就不会执行循环中的代码。
那么如果我们改成如下代码呢:
int i;
for (i = 1; i < 10; ++i )
{
   Console.WriteLine("{0}",i);
}
Console.ReadKey();


结果如下:
2.png

现在 就知道>=和>条件的区别的了吧 当然<= ;<同样道理

还有要说明的是,C# 对大小写敏感,也就是说A和a会被当成两个不同的变量。

好吧回来继续我们的分析:

for (imagCood = 1.2;  imagCood >= 1.2; imagCood -= 0.05)
{
     for(realCood = -0.6; realCood <= 1.77; realCood += 0.03)
          {

          }
}


两个for循环,迭代图像中所有点的坐标。

(这里选择合适的边界值来显示Mandelbrot图像的主要部分,如果要放大这个图像,可以放大这些边界)
(为了方便 下文Mandelbrot图像 一律用M图像表示)

在这两个循环中,代码处理M图像中的一个点,给N指定一个值。这段代码执行要求的迭代计算,给定当前点的测试值。
首先初始化一些变量
iterations = 0;
realTemp = realCoord;
imagTemp = imagCoord;
arg = (realCoord * realCoord)+(imagCoord * imagCoord);
接着用while循环执行迭代。使用while循环,而不是do循环,是为了防止N的初始值大于2,如果N大于2,iterations=0就是需要的答案,不需要计算了。
注意这里没有全面计算参数,而仅获取x*x+y*y的值,并检查该值是否小于4,这样简化了计算,因为我们已经知道2是4的平方根,所以不用再计算了

while((arg<4)&&(iterations<40))
{
  realTemp2 = (realTemp * realTemp )-(imagTemp * imagTemp) - realCoord;
  imagTemp = (2 * realTemp * imagTemp) - imagCoord;
  realTemp = realTemp2;
arg = (realTemp * realTemp) + (imagTemp * imagTemp);
  iterations +=1;
}
  这个循环计算上述的数值,其最大迭代数是40.
  把当前点的值存储在iterations后,再使用switch语句选择要输出的字符。这里只使用4个不同字符,而不是40个,切使用求余运算(%),这样0、4、8等使用一个字符,1、5、9等使用另一个字符,以此类推:
switch (iterations % 4)
                    {
                        case 0:
                            Console.Write("。");
                            break;
                        case 1:
                            Console.Write("S");
                            break;
                        case 2:
                            Console.Write("B");
                            break;
                        case 3:
                            Console.Write("草");
                            break;
                    }

注意这里使用的是Console.Write(),如不是Console.WriteLine(),因为每次输出一个字符时,并不需要从一个新的行开始,在最内层的一个for循环结束后,需要结束一行,所以使用\n字符串来代替回车换行:
Console.Write("\n");

这样每行都与下一行分割开来,并进行适当的排列。这个应用程序的最终结果尽管不是很漂亮 单也能给人留下深刻印象,他展现了循环和分支的用途。
也让人认识到分型的美。
结果我就不贴出来了 很漂亮 大家可以自己试试!






评分

参与人数 10HB +21 THX +7 收起 理由
29590 + 1
消逝的过去 + 2
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
agan8888 + 1
EMT + 1 + 1
ding520 + 1 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
yAxI丶9y + 1 支持!我很赞同!
zx2cwf + 5 + 1 我很赞同!
王尼玛 + 5 + 1 积极评分从我做起,感谢!
Shark恒 + 5 + 1 我很赞同!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
张博 发表于 2014-11-7 16:48 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
柠檬狗丶 发表于 2014-11-7 16:54 | 显示全部楼层

看起来很厉害的样子!!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
Shark恒 发表于 2014-11-7 16:56 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
 楼主| 大官人 发表于 2014-11-7 17:10 | 显示全部楼层

求加分啊 求顶啊啊啊啊  纯手打哇
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
王尼玛 发表于 2014-11-7 19:51 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
虚竹 发表于 2014-11-7 21:49 | 显示全部楼层

...写了这么多!好像好厉害的样子!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
zx2cwf 发表于 2014-11-8 09:44 | 显示全部楼层

哦也  只能来膜拜一下了
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表