我创建了一个Python文件来生成Mandelbrot集图像。原始数学代码不是我的,所以我不理解它 - 我只是对其进行了大量修改,使其速度提高了约250倍(线程规则!)。
无论如何,我想知道如何修改代码的数学部分以使其呈现一个特定的位。这是数学部分:
for y in xrange(size[1]):
coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth))
z = complex(coords[0],coords[1])
o = complex(0,0)
dotcolor = 0 # default, convergent
for trials in xrange(n):
if abs(o) <= 2.0:
o = o**2 + z
else:
dotcolor = trials
break # diverged
im.putpixel((x,y),dotcolor)
尺寸定义:
size1 = 500
size2 = 500
n=64
box=((-2,1.25),(0.5,-1.25))
plus = size[1]+size[0]
uleft = box[0]
lright = box[1]
xwidth = lright[0] - uleft[0]
ywidth = uleft[1] - lright[1]
我需要修改什么才能使其呈现集合的某个部分?
答案 0 :(得分:14)
该行:
box=((-2,1.25),(0.5,-1.25))
是定义正在渲染的坐标空间区域的位,因此您只需要更改此行。第一个坐标对是区域的左上角,第二个是右下角。
从图像中获取新坐标应该非常简单。你有两个坐标系,你的“图像”系统大小为100x100像素,原点为(0,0)。而你的“复杂”平面坐标系由“盒子”定义。对于X:
X_complex=X_complex_origin+(X_image/X_image_width)*X_complex_width
答案 1 :(得分:4)
了解如何执行此操作的关键是了解coords =
行正在做什么:
coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth))
实际上,您循环的x
和y
值对应于屏幕上像素的坐标,正在被转换到正在查看的复平面上的对应点。这意味着(0,0)
屏幕坐标将转换为查看(-2,1.25)
的左上区域,(1,0)
将相同,但移动距离的1/500(假设500像素) -2
和0.5
x坐标之间的宽度窗口。
这正是该行正在做的事情 - 我将仅使用更多说明性变量名称扩展X坐标位来表示:
mandel_x = mandel_start_x + (screen_x / screen_width) * mandel_width
(mandel_
变量指的是复平面上的坐标,screen_
变量指的是被绘制像素的屏幕坐标。)
如果你想让屏幕的一个区域放大,你想要完全相同:取左上和右下区域的屏幕坐标,将它们转换为复平面坐标,并使那些新的uleft和lright变量。即放大由屏幕坐标(x1,y1)...(x2,y2)分隔的框,使用:
new_uleft = (uleft[0] + (x1/size[0]) * (xwidth), uleft[1] - (y1/size[1]) * (ywidth))
new_lright = (uleft[0] + (x2/size[0]) * (xwidth), uleft[1] - (y2/size[1]) * (ywidth))
(显然你需要根据新坐标重新计算大小,xwidth,ywidth和其他因变量)
如果你很好奇,mandelbrot集背后的数学并不复杂(只是复杂)。 它所做的只是采用一个特定的坐标,将其视为一个复数,然后反复对其进行平方并将原始数字添加到其中。
对于某些数字,这样做会导致结果发散,在重复此过程时不断向无穷大方向发展。对于其他人来说,它总是会保持在一定水平以下(例如,显然(0.0,0.0)在这个过程中永远不会变得更大.mandelbrot集合(黑色区域)是那些没有发散的坐标。已经证明,如果任何数字都高于5的平方根,它会发散 - 你的代码只是使用2.0
作为sqrt(5)
(〜2.236
)的近似值,但这不会太明显差异。
通常,发散的区域会与过程的迭代次数一起绘制,超过此值(代码中的trials
变量),这将产生彩色区域。