rhy*_*o98 3 python rendering pygame fractals
目前,我正在使用生成 Julia 集和 Mandelbrot 集的脚本,然后使用 pygame 来渲染点。
本质上,屏幕被映射到一个较小的坐标系,其边界为 x 轴上的 -2.5, 2.5 和 y 轴上的 -1, 1。然后将此映射范围中的每个像素传递给一个函数,以检查其等价的复数是否在给定的集合中。此函数返回计算该数字是否在集合中(或最大迭代次数)所花费的迭代次数。
然后,对于每个像素,我知道根据此迭代分数为它着色什么颜色,并逐个渲染每个像素。这部分过程非常密集,需要大约 30 秒的时间来渲染,但根据场景的复杂程度,可能会更多。
这是用于确定传递的复数和复坐标是否在 Julia 集中的代码,在检查 1920 * 1080 像素时根本不需要很长时间计算:
max_iter = 45
def julia(z, c):
n = 0
while abs(z) <= 2 and n < max_iter:
z = z * z + c
n += 1
return n
Run Code Online (Sandbox Code Playgroud)
这是我用于pygame渲染的代码,这绝对是问题所在:
size_ = 1920, 1080
re_ = -2.5, 2.5
im_ = -1, 1
surf = pygame.Surface(size)
colour_gradient1 = [c, c1, c2, c3, ...] # This is some list of colours generated by a gradient function
for x in range(0, size_[0]):
for y in range(0, size_[1]):
z = complex(re_[0] + (x / size_[0]) * (re_[1] - re_[0]),
im_[0] + (y / size_[1]) * (im_[1] - im_[0]))
m = julia(z, c)
colour = colour_gradient1[m]
pygame.draw.rect(surf,
colour,
(x, y, 1, 1))
Run Code Online (Sandbox Code Playgroud)
我想我理解为什么这是性能密集型的,因为 pygame 和 python 都没有真正优化用于将内容渲染到这样的屏幕上。我目前正在尝试学习 C++ 并且我更了解它对于这样的东西。
我还尝试了一个缩放功能,我可以用鼠标选择一个框,脚本会渲染这个选定的区域,但实现这就是问题突出的地方。随着放大的分形变得更加复杂,脚本需要很长时间才能使用此功能。
所以我的问题是,有没有更好的方法可以使用 python 或者 pygame 近乎实时地渲染这样的东西?我愿意使用不同的软件包,但如果可以通过 pygame 进行,那将是理想的。
分形生成算法总是在你放大的时候减慢速度,因为你越深入(或在达到救助之前)每个像素需要更多的迭代。
这在解释性语言中永远不会特别快。当然,您可以调整它以稍微提高速度,但对于所有缩放级别,它永远不会是“实时”(例如 < 1 秒/图像)。
如果您想继续使用 Python,您将不得不承认它永远不会很快。
然而。但是,您可以将每个象限的生成拆分为单独的进程,每个进程都在自己的 CPU/内核上运行。这会给你一个 N/核加速。
有一些优化可以通过检测图像中的对称性来执行,并且只计算一半的像素,因为另一侧是它的一面镜子(就像水平轴通过缩小的Mandelbrot 集)。您可能可以参考古老的Fractint Program的来源以获取示例。
...
旁白:我使用 nVidia CUDA库在 C 中编写了其中一个(绘制Mandelbrot 集),该库将计算扩展到视频卡上的 1200 个“CPU”(使用中档 2018 笔记本电脑)。虽然它工作得非常快,但对于足够大的图像或深度“放大”的分形,它仍然变得很慢。涉及的数字运算实在是太多了。
| 归档时间: |
|
| 查看次数: |
291 次 |
| 最近记录: |