曼德波罗集图片生成
图片效果
第一次生成,图片上的每个像素都是唯一的一个坐标,即坐标
(
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()