You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mandelbrot集渲染程序输出呈反转四分块问题求助

修复Mandelbrot集渲染的四分块翻转问题

问题根源分析

你的代码存在三个核心问题导致图像呈现四分块且方向错误:

  • 像素坐标映射错误:直接将数学坐标x、i作为图像像素坐标传入putpixel,但图像像素坐标范围是(0,0)到(999,499),而你使用的x(默认-550到450)、i(默认-250到250)包含负数,PIL会将负数坐标循环到图像另一侧,造成四分块错位。
  • 坐标系方向不匹配:PIL图像的y轴向下递增,而数学坐标系的y轴向上递增,直接使用会导致图像上下翻转。
  • 逃逸判断逻辑不严谨:通过字符串判断zofn是否为nan的方式不可靠,Mandelbrot集的标准逃逸条件是当|z| > 2时,点会趋向无穷,属于逃逸点。

修复后的代码

from PIL import Image
from PIL import ImageShow
from PIL import ImageColor as ImageColour

colours = ["navy","darkblue","blue","cornflowerblue","lightsteelblue","lightskyblue","turquoise","palegreen","lawngreen","greenyellow","yellowgreen","goldenrod","gold","yellow","darkorange","orange","brown","maroon","red","deeppink","darkmagenta","magenta","mediumorchid","darkviolet","slateblue"]

def testpoint(c, max_iter):
    z = 0.0
    count = 0
    while abs(z) <= 2 and count < max_iter:
        z = z * z + c
        count += 1
    # 达到最大迭代次数未逃逸则属于Mandelbrot集
    return count if abs(z) > 2 else -1

def mainprogram():
    # 处理输入默认值:用户直接回车时取默认值
    zoom_input = input("Set Zoom Level. (Default: 10)     ")
    zoom = int(zoom_input or 10) * 10
    
    centre_x_input = input("Input centre x value. (Default: -50)     ")
    centre_x = int(centre_x_input or -50)
    
    centre_y_input = input("Input centre y value. (Default: 0)     ")
    centre_y = int(centre_y_input or 0)

    img_width = 1000
    img_height = 500
    max_iter = 5 * zoom

    for img_y in range(img_height):
        # 翻转y轴并映射到数学坐标系
        math_y = (centre_y + 250 - img_y) / zoom
        for img_x in range(img_width):
            # 映射x坐标到数学坐标系
            math_x = (centre_x - 500 + img_x) / zoom
            c = complex(math_x, math_y)
            value = testpoint(c, max_iter)
            
            colour = (0, 0, 0) if value == -1 else ImageColour.getrgb(colours[value % len(colours)])
            result.putpixel((img_x, img_y), colour)
        print(f"line {img_y + 1} done")
    
    ImageShow.show(result)
    # 注释下方代码可避免无限递归请求输入
    # mainprogram()

# 初始化图像画布
result = Image.new("RGB", (1000, 500), "Black")
mainprogram()

关键修复点说明

  • 坐标映射修正:
    • 图像x坐标img_x从0到999,映射为数学x坐标:(centre_x - 500 + img_x) / zoom,确保对应设定的中心左右500单位范围。
    • 图像y坐标img_y从0到499,先翻转得到250 - img_y,再叠加中心y偏移后缩放:(centre_y + 250 - img_y) / zoom,解决上下翻转问题。
  • 逃逸判断优化:用abs(z) <= 2替代字符串判断,逻辑准确且效率更高。
  • 输入默认值修复:原代码中input(...) or 10的写法存在逻辑漏洞,改为先接收输入再处理默认值。
  • 避免无限递归:原代码末尾递归调用自身会导致程序无限循环请求输入,建议注释该调用。

内容的提问来源于stack exchange,提问作者Jessica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 08:43:19