浅析Mandelbrot集合及其图形的绘制

简介:

引言

在《Foundations of F#》的第七章中,作者在介绍Math命名空间时举的例子是绘制Mandelbrot集合。这个看起来挺奇怪的东东以前还真没见过,网上一查才知道,原来它是如此的优美动人。由于该集合的定义与分形相关,所以先来了解下分形的概念。

什么是分形(Fractal)

1967年,美国数学家Mandelbrot曾出这样一个著名的问题:英格兰的海岸线到底有多长?这个问题在数学上可以理解为:用折线段拟合任意不规则的连续曲线是否一定有效?这个问题的提出实际上是对以欧氏几何为核心的传统几何的挑战。

1975年,Mandelbrot在其《自然界中的分形几何》一书中引入了分形(fractal)这一概念。从字面意义上讲, fractal是碎块、碎片的意思,然而这并不能概括Mandelbrot的分形概念,尽管目前还没有一个让各方都满意的分形定义,但在数学上大家都认为分形有以下几个特点:

1. 具有无限精细的结构;
2. 比例自相似性;
3. 一般它的分数维大子它的拓扑维数;
4. 可以由非常简单的方法定义,并由递归、迭代产生。

    据说,南非海岸线的维数是1.02,英国西岸的维数是1.25。

    下面的两幅图有助于我们理解它的概念:

    fractal1

    fractal2

    需要注意的是,分形往往由递归、迭代产生,但是我们在纸上做出的图只能作有限次的递归、迭代。

    分形几何学已在自然界与物理学中得到了应用。如在显微镜下观察落入溶液中的一粒花粉,会看见它不间断地作无规则运动(布朗运动),这是花粉在大量液体分子的无规则碰撞(每秒钟多达十亿亿次)下表现的平均行为。布朗粒子的轨迹,由各种尺寸的折线连成。只要有足够的分辨率,就可以发现原以为是直线段的部分,其实由大量更小尺度的折线连成。

    什么是Mandelbrot集合?

    Mandelbrot集合是在复平面上组成分形的点的集合,它正是以数学家Mandelbrot命名。

    Mandelbrot集合可以用复二次多项式

    f_ c(z) =z^{2}+ c \, 来定义

    其中c是一个复参数。对于每一个c,从z = 0\,开始对fc(z)进行迭代。

    序列 (0, f_ c(0), f_c(f_ c(0)), f_ c(f_ c(f_ c(0))), \ldots) 的元素的模(复数具有模的概念)或者延伸到无穷大,或者只停留在有限半径的圆盘内。Mandelbrot集合就是使以上序列不延伸至无限大的所有c点的集合。

    从数学上来讲,Mandelbrot集合是一个复数的集合。一个给定的复数c或者属于Mandelbrot集合M,或者不属于。比如,取c = 1,那么这个序列就是(0, 1, 2, 5, 26, ...),显然它的值会趋于无穷大;而如果取c = i,那么序列就是(0, i, -1+i, -i, -1+i, -i,...),它的值会一直停留在有限半径的圆盘内。

    事实上,一个点属于Mandelbrot集合当且仅当它对应的序列(由上面的二项式定义)中的任何元素的模都不大于2。这里的2就是上面提到的“有限半径”。

    在计算机上绘制Mandelbrot集合

    计算机的屏幕上的像素只有有限个,而Mandelbrot集合中的点则有无限个。

    Mandelset_hires

    观察上面复平面的局部,Mandelbrot集合即黑色区域,实部从-2到1,虚部从-1到1,那么将两个点(-2, 1)和(1, -1)作为一个矩形的左上角顶点和右下角顶点,那么这个矩形就包含了整个Mandelbrot集合,该矩形的长为3,宽为2。我们可以将这个矩形与屏幕上的区域进行映射,也就是将屏幕上的一个像素映射为该矩形内的一点,如果该点属于Mandelbrot集合,就将该像素着为黑色,这样逐一对每个像素进行判断和着色,就可以模拟绘制Mandelbrot集合了。该矩形的长宽比为3:2,我们在屏幕上可以取600 * 400的矩形区域。

    完成映射后来考虑如何判断一个点是否属于该集合。其根据就是上面的结论“一个点属于Mandelbrot集合当且仅当它对应的序列(由上面的二项式定义)中的任何元素的模都不大于2”,由于序列的的元素有无穷多个,我们只能取有限的迭代次数来模拟了,比如取100或1000次。

    我们用Microsoft.FSharp.Math.Notation.complex类型来表示一个复数,它的Magnitude属性表示复数的模,我们可以通过一定次数(比如100次)的迭代,来看看前100项是不是都满足条件,如果满足就认为这个复数在Mandelbrot集合内。下面是完整的程序。

    复制代码
    F# Code - 绘制Mandelbrot集合
    #light
    open System
    open System.Drawing
    open System.Windows.Forms
    open Microsoft.FSharp.Math
    open Microsoft.FSharp.Math.Notation

    // 迭代次数
    let maxIterations = 100

    // 映射比例
    let scalingFactor = 1.0 / 200.0
    // 将像素映射为复数
    let mapPlane(x, y) =
    let fx = ((float x) * scalingFactor) - 2.0
    let fy = ((float y) * scalingFactor) - 1.0
    complex fx fy

    let mutable iteration = 0
    let mutable current = complex 0.0 0.0
    let mutable temp = complex 0.0 0.0

    let form =
    let image = new Bitmap(600, 400)
    for x = 0 to image.Width - 1 do
    for y = 0 to image.Height - 1 do
    iteration
    <- 0
    current
    <- mapPlane(x, y)
    temp
    <- current
    // 判断当前点是否在Mandelbrot集合内
    while(temp.Magnitude <= 2.0 && iteration < maxIterations) do
    temp
    <- temp * temp + current
    iteration
    <- iteration + 1

    // 如果在,像素为黑色
    if iteration = maxIterations then
    image.SetPixel(x, y, Color.Black)
    else
    image.SetPixel(x, y, Color.White)

    let temp = new Form() in
    temp.Paint.Add(
    fun e -> e.Graphics.DrawImage(image, 0, 0))
    temp.Height
    <- 435
    temp.Width
    <- 600
    temp.Text
    <- "Draw Mandelbrot Set"
    temp

    [<STAThread
    >]
    do Application.Run(form)
    复制代码

    下面是效果图

    这张图是黑白的,我们可以把它变成彩色的。看这一部分代码:

    复制代码
    F# Code
    // 如果在,像素为黑色
    if iteration = maxIterations then
    image.SetPixel(x, y, Color.Black)
    else
    image.SetPixel(x, y, Color.White)
    复制代码

    只有iteration等于maxIterations,当前的复数才属于Mandelbrot集合,这时将像素着为黑色;如果不在集合内,我们可以想办法着为彩色。考虑红橙黄绿蓝靛紫七种颜色,把它们存储在数组中,然后根据iteration的值来取相应的颜色:

    复制代码
    Code
    // 七种颜色
    let colors = [| Color.Red; Color.Orange; Color.Yellow;
    Color.Green; Color.Blue; Color.Indigo;
    Color.Purple;
    |]

    // 如果在,像素为黑色
    if iteration = maxIterations then
    image.SetPixel(x, y, Color.Black)
    else
    image.SetPixel(x, y, colors.[iteration % colors.Length])
    复制代码

    完整的代码是:

    F# Code - 彩色的Mandelbrot

    下面是效果图

    当然这只是着彩色方式的一种,如果你有兴趣,可以查看后面给出的参考文章。

    小结

    Mandelbrot集合的图形表示可以让我们认识到纯粹的数学之美,与之相关的分形几何学则是无处不在的,不得不感叹数学的力量。由于分形几何学知识的匮乏,本文只能给出Mandelbrot集合的定义,并以最容易理解的方式绘制出该集合。这里使用的语言是F#,而不是C#,以后会尽量作出一些采用F#的更为实用的例子。

    参考:

    《Foundations of F#》 by Robert Pickering
    神奇的分形艺术
    Mandelbrot_Set_Wikipedia
    分形是什么?


    本文转自一个程序员的自省博客园博客,原文链接:http://www.cnblogs.com/anderslly/archive/2008/10/10/mandelbrot-set-by-fsharp.html,如需转载请自行联系原作者。

    目录
    相关文章
    |
    存储 Cloud Native Linux
    C++ vector元素类型为什么不能是引用
    C++ vector元素类型为什么不能是引用
    |
    6月前
    |
    存储 容器 API
    鸿蒙特效教程03-水波纹动画效果实现教程
    本教程适合HarmonyOS初学者,通过简单到复杂的步骤,一步步实现漂亮的水波纹动画效果。
    219 0
    鸿蒙特效教程03-水波纹动画效果实现教程
    |
    SQL 消息中间件 Java
    SpringBoot整合RocketMQ发送消息过滤
    消息者在进行消息订阅时,除了可以指定要订阅消息的Topic外,还可以对指定Topic中的消息根据指定条件进行过滤,即可以订阅比Topic更加细粒度的消息类型。 对于指定Topic消息的过滤有两种过滤方式:Tag过滤与SQL过滤
    |
    人工智能 搜索推荐 算法
    数据平台演进问题之数据库技术面临挑战如何解决
    数据平台演进问题之数据库技术面临挑战如何解决
    294 0
    |
    10月前
    |
    Linux 文件存储 Windows
    linux软连接详解!!!
    本文介绍了Linux文件类型、文件属性、文件存储机制以及软链接和硬链接的概念。主要内容包括:Linux文件类型及其识别方法、文件属性的组成及查看方式、inode和block的作用、软链接和硬链接的区别及应用场景。通过具体示例,帮助读者理解Linux文件系统的运作原理。
    662 2
    linux软连接详解!!!
    |
    关系型数据库 分布式数据库 数据库
    2024年全国大学生计算机系统能力大赛PolarDB数据库创新设计赛(天池杯)等你来战!
    2024年全国大学生计算机系统能力大赛PolarDB数据库创新设计赛(天池杯)等你来战!
    693 15
    2024年全国大学生计算机系统能力大赛PolarDB数据库创新设计赛(天池杯)等你来战!
    |
    Kubernetes 负载均衡 应用服务中间件
    深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
    深入理解 Kubernetes Ingress:路由流量、负载均衡和安全性配置
    2135 1
    |
    SQL 关系型数据库 MySQL
    MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结
    MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结
    396 1
    |
    设计模式 数据可视化 关系型数据库
    设计之美-揭秘设计模式、原则与UML的魔法
    设计模式、设计原则和UML是软件工程设计中的核心要素。设计模式为常见问题提供经验证的解决方案,复用性高且提升开发效率。设计原则指导我们创建灵活、可维护和可扩展的系统,确保代码质量和长期可维护性。UML(统一建模语言)则是一种强大的可视化工具,用于描述、构建和文档化软件系统的结构和行为。它帮助开发者更清晰地理解系统架构和组件间关系。综合应用设计模式、设计原则和UML,能够显著提高软件开发的效率和质量,减少维护成本,为复杂系统的设计和实施提供有力支持。
    245 0
    设计之美-揭秘设计模式、原则与UML的魔法
    |
    算法 计算机视觉
    图像处理之水波纹扩散效果(water ripple effect)
    图像处理之水波纹扩散效果(water ripple effect)
    348 5