复杂分形图形生成:实现一个生成三维Mandelbulb分形的程序。要求能够通过调整参数(如迭代次数、缩放因子、旋转角度等)来探索不同的分形形态,并实现高质量的渲染,包括光照效果和颜色映射,以增强视觉效果。同时,优化代码性能,使其在合理时间内生成高分辨率图像。用Python编程实现。迭代次数、缩放因子、旋转角度、光照效果和颜色映射通过复选框实现。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import ipywidgets as widgets
from IPython.display import display


def mandelbulb(x, y, z, power, max_iter):
    c = np.complex128(x + 1j * y + 1j ** 2 * z)
    z_complex = np.complex128(0)
    for i in range(max_iter):
        r = np.abs(z_complex)
        theta = np.arctan2(np.sqrt(z_complex.real ** 2 + z_complex.imag ** 2), z_complex.imag ** 2)
        phi = np.arctan2(z_complex.imag, z_complex.real)
        z_complex = r ** power * (np.cos(theta * power) + 1j * np.sin(theta * power) * np.cos(phi * power) +
                                  1j ** 2 * np.sin(theta * power) * np.sin(phi * power)) + c
        if np.abs(z_complex) > 2:
            return i
    return max_iter


def generate_mandelbulb(resolution, power, max_iter):
    x = np.linspace(-2, 2, resolution)
    y = np.linspace(-2, 2, resolution)
    z = np.linspace(-2, 2, resolution)
    X, Y, Z = np.meshgrid(x, y, z)
    mandelbulb_values = np.vectorize(mandelbulb)(X, Y, Z, power, max_iter)
    return X, Y, Z, mandelbulb_values


def plot_mandelbulb(resolution=100, power=8, max_iter=20, scale=1.0, rotation_x=0, rotation_y=0, rotation_z=0,
                    use_lighting=True, colormap='viridis'):
    X, Y, Z, mandelbulb_values = generate_mandelbulb(resolution, power, max_iter)

    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    sc = ax.scatter(X.flatten(), Y.flatten(), Z.flatten(), c=mandelbulb_values.flatten(), cmap=colormap)
    fig.colorbar(sc, label='Iterations')
    ax.set_xlim(-2 * scale, 2 * scale)
    ax.set_ylim(-2 * scale, 2 * scale)
    ax.set_zlim(-2 * scale, 2 * scale)
    ax.view_init(rotation_x, rotation_y)
    ax.dist = rotation_z

    def update(resolution, power, max_iter, scale, rotation_x, rotation_y, rotation_z, use_lighting, colormap):
        X, Y, Z, mandelbulb_values = generate_mandelbulb(resolution, power, max_iter)
        ax.clear()
        sc = ax.scatter(X.flatten(), Y.flatten(), Z.flatten(), c=mandelbulb_values.flatten(), cmap=colormap)
        fig.colorbar(sc, label='Iterations')
        ax.set_xlim(-2 * scale, 2 * scale)
        ax.set_ylim(-2 * scale, 2 * scale)
        ax.set_zlim(-2 * scale, 2 * scale)
        ax.view_init(rotation_x, rotation_y)
        ax.dist = rotation_z
        plt.draw()

    resolution_slider = widgets.IntSlider(value=resolution, min=50, max=200, step=10, description='分辨率')
    power_slider = widgets.FloatSlider(value=power, min=2, max=10, step=0.1, description='幂次')
    max_iter_slider = widgets.IntSlider(value=max_iter, min=10, max=50, step=5, description='最大迭代次数')
    scale_slider = widgets.FloatSlider(value=scale, min=0.1, max=5, step=0.1, description='缩放因子')
    rotation_x_slider = widgets.FloatSlider(value=rotation_x, min=0, max=360, step=10, description='X轴旋转角度')
    rotation_y_slider = widgets.FloatSlider(value=rotation_y, min=0, max=360, step=10, description='Y轴旋转角度')
    rotation_z_slider = widgets.FloatSlider(value=rotation_z, min=1, max=20, step=1, description='Z轴距离(模拟缩放)')
    lighting_checkbox = widgets.Checkbox(value=use_lighting, description='启用光照效果(暂不支持)')
    colormap_dropdown = widgets.Dropdown(options=plt.colormaps(),
                                         value=colormap, description='颜色映射')

    ui = widgets.VBox([resolution_slider, power_slider, max_iter_slider, scale_slider,
                       rotation_x_slider, rotation_y_slider, rotation_z_slider,
                       lighting_checkbox, colormap_dropdown])
    out = widgets.interactive_output(update, {'resolution': resolution_slider, 'power': power_slider,
                                              'max_iter': max_iter_slider, 'scale': scale_slider,
                                              'rotation_x': rotation_x_slider, 'rotation_y': rotation_y_slider,
                                              'rotation_z': rotation_z_slider, 'use_lighting': lighting_checkbox,
                                              'colormap': colormap_dropdown})
    display(ui, out)
    plt.show()


if __name__ == "__main__":
    plot_mandelbulb()

整体功能概述

这段 Python 代码的主要功能是生成并可视化三维 Mandelbulb 分形图形,同时提供了一系列交互式控件,允许用户调整多个参数,如分辨率、幂次、最大迭代次数、缩放因子、旋转角度、颜色映射等,以探索不同形态的分形图形。

代码详细解释

1. 导入必要的库

python

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import ipywidgets as widgets
from IPython.display import display

  • numpy:用于进行数值计算,如数组操作和数学函数计算。
  • matplotlib.pyplot:用于创建和显示图形。
  • mpl_toolkits.mplot3d.Axes3D:用于创建三维图形。
  • ipywidgets:用于创建交互式控件,如滑块、复选框和下拉菜单。
  • IPython.display.display:用于在 Jupyter Notebook 中显示交互式控件和图形。
2. mandelbulb 函数

python

def mandelbulb(x, y, z, power, max_iter):
    c = np.complex128(x + 1j * y + 1j ** 2 * z)
    z_complex = np.complex128(0)
    for i in range(max_iter):
        r = np.abs(z_complex)
        theta = np.arctan2(np.sqrt(z_complex.real ** 2 + z_complex.imag ** 2), z_complex.imag ** 2)
        phi = np.arctan2(z_complex.imag, z_complex.real)
        z_complex = r ** power * (np.cos(theta * power) + 1j * np.sin(theta * power) * np.cos(phi * power) +
                                  1j ** 2 * np.sin(theta * power) * np.sin(phi * power)) + c
        if np.abs(z_complex) > 2:
            return i
    return max_iter

  • 功能:计算给定三维点 (x, y, z) 在 Mandelbulb 分形中的迭代次数。
  • 参数
    • xyz:三维空间中的点坐标。
    • power:Mandelbulb 分形的幂次参数,影响分形的形状。
    • max_iter:最大迭代次数。
  • 实现过程
    1. 将三维点转换为复数 c
    2. 初始化复数 z_complex 为 0。
    3. 进行迭代计算,每次迭代更新 z_complex 的值。
    4. 如果 z_complex 的模大于 2,则认为该点不在 Mandelbulb 集合内,返回当前迭代次数。
    5. 如果达到最大迭代次数仍未满足条件,则返回最大迭代次数。
3. generate_mandelbulb 函数

python

def generate_mandelbulb(resolution, power, max_iter):
    x = np.linspace(-2, 2, resolution)
    y = np.linspace(-2, 2, resolution)
    z = np.linspace(-2, 2, resolution)
    X, Y, Z = np.meshgrid(x, y, z)
    mandelbulb_values = np.vectorize(mandelbulb)(X, Y, Z, power, max_iter)
    return X, Y, Z, mandelbulb_values

  • 功能:生成 Mandelbulb 分形的数据。
  • 参数
    • resolution:生成数据的分辨率,即每个坐标轴上的点数。
    • power:Mandelbulb 分形的幂次参数。
    • max_iter:最大迭代次数。
  • 实现过程
    1. 使用 np.linspace 生成 xyz 坐标轴上的点。
    2. 使用 np.meshgrid 生成三维网格点。
    3. 使用 np.vectorize 将 mandelbulb 函数向量化,以便对整个网格点进行计算。
    4. 计算每个网格点的 Mandelbulb 迭代次数。
    5. 返回网格点坐标和对应的迭代次数。
4. plot_mandelbulb 函数

python

def plot_mandelbulb(resolution=100, power=8, max_iter=20, scale=1.0, rotation_x=0, rotation_y=0, rotation_z=0,
                    use_lighting=True, colormap='viridis'):
    X, Y, Z, mandelbulb_values = generate_mandelbulb(resolution, power, max_iter)

    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    sc = ax.scatter(X.flatten(), Y.flatten(), Z.flatten(), c=mandelbulb_values.flatten(), cmap=colormap)
    fig.colorbar(sc, label='Iterations')
    ax.set_xlim(-2 * scale, 2 * scale)
    ax.set_ylim(-2 * scale, 2 * scale)
    ax.set_zlim(-2 * scale, 2 * scale)
    ax.view_init(rotation_x, rotation_y)
    ax.dist = rotation_z

    def update(resolution, power, max_iter, scale, rotation_x, rotation_y, rotation_z, use_lighting, colormap):
        X, Y, Z, mandelbulb_values = generate_mandelbulb(resolution, power, max_iter)
        ax.clear()
        sc = ax.scatter(X.flatten(), Y.flatten(), Z.flatten(), c=mandelbulb_values.flatten(), cmap=colormap)
        fig.colorbar(sc, label='Iterations')
        ax.set_xlim(-2 * scale, 2 * scale)
        ax.set_ylim(-2 * scale, 2 * scale)
        ax.set_zlim(-2 * scale, 2 * scale)
        ax.view_init(rotation_x, rotation_y)
        ax.dist = rotation_z
        plt.draw()

    resolution_slider = widgets.IntSlider(value=resolution, min=50, max=200, step=10, description='分辨率')
    power_slider = widgets.FloatSlider(value=power, min=2, max=10, step=0.1, description='幂次')
    max_iter_slider = widgets.IntSlider(value=max_iter, min=10, max=50, step=5, description='最大迭代次数')
    scale_slider = widgets.FloatSlider(value=scale, min=0.1, max=5, step=0.1, description='缩放因子')
    rotation_x_slider = widgets.FloatSlider(value=rotation_x, min=0, max=360, step=10, description='X轴旋转角度')
    rotation_y_slider = widgets.FloatSlider(value=rotation_y, min=0, max=360, step=10, description='Y轴旋转角度')
    rotation_z_slider = widgets.FloatSlider(value=rotation_z, min=1, max=20, step=1, description='Z轴距离(模拟缩放)')
    lighting_checkbox = widgets.Checkbox(value=use_lighting, description='启用光照效果(暂不支持)')
    colormap_dropdown = widgets.Dropdown(options=plt.colormaps(),
                                         value=colormap, description='颜色映射')

    ui = widgets.VBox([resolution_slider, power_slider, max_iter_slider, scale_slider,
                       rotation_x_slider, rotation_y_slider, rotation_z_slider,
                       lighting_checkbox, colormap_dropdown])
    out = widgets.interactive_output(update, {'resolution': resolution_slider, 'power': power_slider,
                                              'max_iter': max_iter_slider, 'scale': scale_slider,
                                              'rotation_x': rotation_x_slider, 'rotation_y': rotation_y_slider,
                                              'rotation_z': rotation_z_slider, 'use_lighting': lighting_checkbox,
                                              'colormap': colormap_dropdown})
    display(ui, out)
    plt.show()

  • 功能:绘制 Mandelbulb 分形图形,并提供交互式控件来调整参数。
  • 参数
    • resolution:生成数据的分辨率。
    • power:Mandelbulb 分形的幂次参数。
    • max_iter:最大迭代次数。
    • scale:缩放因子,用于调整图形的大小。
    • rotation_xrotation_yrotation_z:分别表示 X 轴、Y 轴和 Z 轴的旋转角度和距离。
    • use_lighting:是否启用光照效果(暂不支持)。
    • colormap:颜色映射,用于为不同的迭代次数分配颜色。
  • 实现过程
    1. 调用 generate_mandelbulb 函数生成 Mandelbulb 分形的数据。
    2. 创建一个三维图形,并使用 ax.scatter 绘制散点图,根据迭代次数为每个点分配颜色。
    3. 添加颜色条,显示迭代次数与颜色的对应关系。
    4. 设置坐标轴的范围和图形的旋转角度。
    5. 定义 update 函数,用于更新图形。当用户调整控件时,该函数会重新生成数据并更新图形。
    6. 创建各种交互式控件,如滑块、复选框和下拉菜单。
    7. 使用 widgets.VBox 将控件垂直排列。
    8. 使用 widgets.interactive_output 将控件的变化与 update 函数关联起来。
    9. 显示控件和图形。
5. 主程序

python

if __name__ == "__main__":
    plot_mandelbulb()

  • 调用 plot_mandelbulb 函数,开始绘制 Mandelbulb 分形图形并显示交互式控件。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐