曼德波罗集图片生成 python

本文介绍了曼德波罗集的生成原理,通过Python代码实现从复数迭代到判断发散与收敛,进而形成灰度及彩色图像的过程。代码展示了如何利用PIL库创建并渲染图像,通过不同方式展示曼德波罗集的局部细节和颜色映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

曼德波罗集图片生成


图片效果

第一次生成,图片上的每个像素都是唯一的一个坐标,即坐标 ( a , b ) (a, b) (a,b),转化为复数 c = a + b i c=a+bi c=a+bi,可以转化成虚数,将它们传入 f ( x ) = x 2 + c f(x)=x^2+c f(x)=x2+c,这里的x是从0开始迭代的,传入的是c。如下:
n 1 = f ( 0 ) = 0 2 + c n 2 = f ( n 1 ) = ( n 1 ) 2 + c n 3 = f ( n 2 ) = ( n 2 ) 2 + c n_{1}=f(0)=0^2+c\\n_{2}=f(n_{1})=(n_{1})^2+c\\n_{3}=f(n_{2})=(n_{2})^2+c n1=f(0)=02+cn2=f(n1)=(n1)2+cn3=f(n2)=(n2)2+c
程序判定为:当迭代100次后结果为无穷,则表示发散,否则表示收敛。

黑色表示不会发散的点,白色表示会发散的点

请添加图片描述

优化一下颜色,将发散的点中,即白色的点中,计算迭代了多少次出现了数据溢出,将这个次数作为一种灰度,则可得到以下图片

在这里插入图片描述

同时还可调整视野,观察一点局部信息

在这里插入图片描述

将迭代的步骤转化成颜色,这样一种映射关系

就可以得到,有着彩色图案的

在这里插入图片描述

如果遍历计算每一个坐标点上表示的虚数,在迭代的过程中走过的点,让图片上像素颜色权重+1,则生成了以下图片。

在这里插入图片描述

在这里插入图片描述

源代码

python版本:3.7.2,使用到的第三方库:PIL

灰度图版本

# -*- encoding: utf-8 -*-
"""
曼德波罗集
2022年08月21日
by littlefean
"""
import math
from PIL import Image
from time import time


def func(x, c):
    """
    曼德波罗集 中使用到的迭代函数
    :param x: 默认从0开始迭代
    :param c: 传入一个复数
    :return:
    """
    try:
        return x ** 2 + c
    except OverflowError:
        return complex(math.nan, math.nan)


def isDivergent(x, y):
    """
    判断一个虚数点是否会发散
    :param x: 实部
    :param y: 虚部
    :return: 是否会发散,迭代到发现发散的次数
    """
    n = complex(x, y)
    num = func(0, n)
    res = False
    step = 0
    for _ in range(100):
        num = func(num, n)
        if isInfComplex(num):
            res = True
            break
        step += 1

    return res, step


def isInfComplex(n: complex):
    # 判断一个复数是否是无穷大
    return math.isnan(n.real) or math.isnan(n.imag)


def main():
    arrayLen = 4096  # 图片边长
    numLen = 1  # 观察的数据范围 x和y均为 -numLen/2 ~ numLen/2 的正方形视野
    arr = [[0] * arrayLen for _ in range(arrayLen)]

    print("二维数组初始化完毕")

    _b = arrayLen / numLen
    _d = numLen / 2
    for y in range(arrayLen):
        for x in range(arrayLen):
            flag, step = isDivergent(x / _b - _d, y / _b - _d)
            arr[y][x] = step if flag else 0
    print("计算完毕")

    # 渲染成图
    img = Image.new("RGB", (arrayLen, arrayLen), (0, 0, 0))
    for y in range(arrayLen):
        for x in range(arrayLen):
            g = arr[y][x] * 10
            img.putpixel((x, y), (g, g, g))
    img.show()
    img.save(f"{str(time())}.png")
    return None


if __name__ == "__main__":
    main()
    # test()

彩色图版本

# -*- encoding: utf-8 -*-
"""
曼德波罗集
2022年08月21日
by littlefean
"""
import math
from PIL import Image
from time import time

from typing import Tuple


def func(x, c):
    """
    曼德波罗集 中使用到的迭代函数
    :param x: 默认从0开始迭代
    :param c: 传入一个复数
    :return:
    """
    try:
        return x ** 2 + c
    except OverflowError:
        return complex(math.nan, math.nan)


def isDivergent(x, y):
    """
    判断一个虚数点是否会发散
    :param x: 实部
    :param y: 虚部
    :return: 是否会发散,迭代到发现发散的次数
    """
    n = complex(x, y)
    num = func(0, n)
    res = False
    step = 0
    for _ in range(100):
        num = func(num, n)
        if isInfComplex(num):
            res = True
            break
        step += 1

    return res, step


def isInfComplex(n: complex):
    # 判断一个复数是否是无穷大
    return math.isnan(n.real) or math.isnan(n.imag)


def stepToColor(step: int) -> Tuple[int, int, int]:
    """将迭代步数转换为颜色,用于渲染"""
    r, g, b = 0, 0, 0
    f = lambda x: int(x * (255 / 33))  # 将0~33映射到0~255
    if step > 66:
        r, g = 255, 255
        b = f(step - 66)
    elif step > 33:
        r = 255
        g = f(step - 33)
    else:
        r = f(step)
    return r, g, b


def main():
    arrayLen = 2048  # 图片边长
    numLen = 4  # 观察的数据范围 x和y均为 -numLen/2 ~ numLen/2 的正方形视野
    arr = [[0] * arrayLen for _ in range(arrayLen)]

    print("二维数组初始化完毕")

    _b = arrayLen / numLen
    _d = numLen / 2
    for y in range(arrayLen):
        for x in range(arrayLen):
            flag, step = isDivergent(x / _b - _d, y / _b - _d)
            arr[y][x] = step if flag else 0
    print("计算完毕")

    # 渲染成图
    img = Image.new("RGB", (arrayLen, arrayLen), (0, 0, 0))
    for y in range(arrayLen):
        for x in range(arrayLen):
            img.putpixel((x, y), stepToColor(arr[y][x]))
    img.show()
    img.save(f"{str(time())}.png")
    return None


if __name__ == "__main__":
    main()
    # test()

版本3

# -*- encoding: utf-8 -*-
"""
曼德波罗集
2022年08月21日
by littlefean
"""
import math
from PIL import Image
from time import time

from typing import Tuple


def func(x, c):
    """
    曼德波罗集 中使用到的迭代函数
    :param x: 默认从0开始迭代
    :param c: 传入一个复数
    :return:
    """
    try:
        return x ** 2 + c
    except OverflowError:
        return complex(math.nan, math.nan)


def isDivergent(x, y):
    """
    判断一个虚数点是否会发散
    :param x: 实部
    :param y: 虚部
    :return: 是否会发散,迭代到发现发散的次数
    """
    n = complex(x, y)
    num = func(0, n)
    res = False
    step = 0
    for _ in range(100):
        num = func(num, n)
        if isInfComplex(num):
            res = True
            break
        step += 1

    return res, step


def isInfComplex(n: complex):
    # 判断一个复数是否是无穷大
    return math.isnan(n.real) or math.isnan(n.imag)


def stepToColor(step: int) -> Tuple[int, int, int]:
    """将迭代步数转换为颜色,用于渲染"""
    r, g, b = 0, 0, 0
    f = lambda x: int(x ** 2 * (255 / 33))  # 将0~33映射到0~255
    if step > 66:
        r, g = 255, 255
        b = f(step - 66)
    elif step > 33:
        r = 255
        g = f(step - 33)
    else:
        r = f(step)
    return r, g, b


def arrayToImg(arr):
    arrayLen = len(arr)
    # 渲染成图
    img = Image.new("RGB", (arrayLen, arrayLen), (0, 0, 0))
    for y in range(arrayLen):
        for x in range(arrayLen):
            img.putpixel((x, y), stepToColor(arr[y][x]))
    img.show()
    img.save(f"{str(time())}.png")


def getPic1():
    arrayLen = 2048  # 图片边长
    numLen = 4  # 观察的数据范围 x和y均为 -numLen/2 ~ numLen/2 的正方形视野
    arr = [[0] * arrayLen for _ in range(arrayLen)]

    print("二维数组初始化完毕")

    _b = arrayLen / numLen
    _d = numLen / 2
    for y in range(arrayLen):
        for x in range(arrayLen):
            flag, step = isDivergent(x / _b - _d, y / _b - _d)
            arr[y][x] = step if flag else 0
    print("计算完毕")
    arrayToImg(arr)
    


def getPic2():
    # 以另一种方式生成图片
    arrayLen = 2048  # 图片边长
    numLen = 4  # 观察的数据范围 x和y均为 -numLen/2 ~ numLen/2 的正方形视野
    arr = [[0] * arrayLen for _ in range(arrayLen)]

    print("二维数组初始化完毕")
    _b = arrayLen / numLen
    _d = numLen / 2
    for y in range(arrayLen):
        for x in range(arrayLen):
            a = x / _b - _d
            b = y / _b - _d
            c = complex(a, b)
            num = func(0, c)
            for _ in range(100):
                num = func(num, c)
                if isInfComplex(num):
                    break
                addX, addY = round(num.real), round(num.imag)
                if 0 <= addX < arrayLen and 0 <= addY < arrayLen:
                    arr[y][x] += 1

    print("计算完毕")
    arrayToImg(arr)
    ...


def main():
    getPic2()
    return None


if __name__ == "__main__":
    main()
    # test()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值