当前位置:

首页 > 编程开发 > 如何使用Python绘制分形图案?

如何使用Python绘制分形图案?

一、目标写一个可以画等边三角形的程序,并且在三角形的每条边上,它必须能够绘制一个稍微小一点的向外的三角形。能够根据人的意愿多次重复此过程,从而创建一些有趣的模式。二、表示图像把图像表示为一个二维的像素阵列。像素阵列中的每个单元格将代表该像素的颜色(RGB)。为此,可以使用NumPy库生成像素数组,并使用Pillow将其转换为可以保存的图像。蓝色像素的x值为3,y值为4,可以通过一个二维数组访问,如pixels[4][3]三、画一条线现在开始编码,首先,需要一个可以获取两组坐标并在它们之间画一条线的函数。下

本文目录

    一、目标

    写一个可以画等边三角形的程序,并且在三角形的每条边上,它必须能够绘制一个稍微小一点的向外的三角形。能够根据人的意愿多次重复此过程,从而创建一些有趣的模式。

    二、表示图像

    把图像表示为一个二维的像素阵列。像素阵列中的每个单元格将代表该像素的颜色(RGB)。

    为此,可以使用NumPy库生成像素数组,并使用Pillow将其转换为可以保存的图像。

    如何使用Python绘制分形图案?

    蓝色像素的x值为3,y值为4,可以通过一个二维数组访问,如pixels[4][3]

    三、画一条线

    现在开始编码,首先,需要一个可以获取两组坐标并在它们之间画一条线的函数。

    下面的代码通过在两点之间插值来工作,每一步都向像素阵列添加新的像素。你可以把这个过程看作是在一条线上逐个像素地进行着色。

    可以在每个代码片段中使用连续字符“\”来容纳一些较长的代码行。

    import numpy as np
    from PIL import Image
    import math
    def plot_line(from_coordinates, to_coordinates, thickness, colour, pixels):
        # 找出像素阵列的边界
        max_x_coordinate = len(pixels[0])
        max_y_coordinate = len(pixels)
        # 两点之间沿着x轴和y轴的距离
        horizontal_distance = to_coordinates[1] - from_coordinates[1]
        vertical_distance = to_coordinates[0] - from_coordinates[0]
        # 两点之间的总距离
        distance =  math.sqrt((to_coordinates[1] - from_coordinates[1])**2 \
                    + (to_coordinates[0] - from_coordinates[0])**2)
        # 每次给一个新的像素上色时,将向前走多远
        horizontal_step = horizontal_distance/distance
        vertical_step = vertical_distance/distance
        # 此时,将进入循环以在像素数组中绘制线
        # 循环的每一次迭代都会沿着线添加一个新的点
        for i in range(round(distance)):
            # 这两个坐标是直线中心的坐标
            current_x_coordinate = round(from_coordinates[1] + (horizontal_step*i))
            current_y_coordinate = round(from_coordinates[0] + (vertical_step*i))
            # 一旦得到了点的坐标,
            # 就在坐标周围画出尺寸为thickness的图案
            for x in range (-thickness, thickness):
                for y in range (-thickness, thickness):
                    x_value = current_x_coordinate + x
                    y_value = current_y_coordinate + y
                    if (x_value > 0 and x_value < max_x_coordinate and \
                        y_value > 0 and y_value < max_y_coordinate):
                        pixels[y_value][x_value] = colour
    # 定义图像的大小
    pixels = np.zeros( (500,500,3), dtype=np.uint8 )
    # 画一条线
    plot_line([0,0], [499,499], 1, [255,200,0], pixels)
    # 把像素阵列变成一张真正的图片
    img = Image.fromarray(pixels)
    # 显示得到的图片,并保存它
    img.show()
    img.save('Line.png')

    如何使用Python绘制分形图案?

    此函数在像素阵列的每个角之间绘制一条黄线时的结果

    四、画三角形

    现在有了一个可以在两点之间画线的函数,可以画第一个等边三角形了。

    给定三角形的中心点和边长,可以使用公式计算出高度:h = ½(√3a)。

    现在利用这个高度、中心点和边长,可以计算出三角形的每个角的位置。使用之前制作的plot_line函数,可以在每个角之间画一条线。

    def draw_triangle(center, side_length, thickness, colour, pixels):
        # 等边三角形的高度是,h = ½(√3a)
        # 其中a是边长
        triangle_height = round(side_length * math.sqrt(3)/2)
        # 顶角
        top = [center[0] - triangle_height/2, center[1]]
        # 左下角
        bottom_left = [center[0] + triangle_height/2, center[1] - side_length/2]
        # 右下角
        bottom_right = [center[0] + triangle_height/2, center[1] + side_length/2]
        # 在每个角之间画一条线来完成三角形
        plot_line(top, bottom_left, thickness, colour, pixels)
        plot_line(top, bottom_right, thickness, colour, pixels)
        plot_line(bottom_left, bottom_right, thickness, colour, pixels)

    如何使用Python绘制分形图案?

    在500x500像素PNG的中心绘制三角形时的结果

    五、生成分形

    一切都已准备就绪,可以用Python创建第一个分形。

    但是最后一步是最难完成的,三角形函数为它的每一边调用自己,需要能够计算每个新的较小三角形的中心点,并正确地旋转它们,使它们垂直于它们所附着的一侧。

    通过从旋转的坐标中减去中心点的偏移量,然后应用公式来旋转一对坐标,可以用这个函数来旋转三角形的每个角。

    def rotate(coordinate, center_point, degrees):
        # 从坐标中减去旋转的点
        x = (coordinate[0] - center_point[0])
        y = (coordinate[1] - center_point[1])
        # Python的cos和sin函数采用弧度而不是度数
        radians = math.radians(degrees)
        # 计算旋转点
        new_x = (x * math.cos(radians)) - (y * math.sin(radians))
        new_y = (y * math.cos(radians)) + (x * math.sin(radians))
        # 将在开始时减去的偏移量加回旋转点上
        return [new_x + center_point[0], new_y + center_point[1]]

    如何使用Python绘制分形图案?

    将每个坐标旋转35度的三角形

    可以旋转一个三角形后,思考如何在第一个三角形的每条边上画一个新的小三角形。

    为了实现这一点,扩展draw_triangle函数,为每条边计算一个新三角形的旋转和中心点,其边长被参数shrink_side_by减少。

    一旦它计算出新三角形的中心点和旋转,它就会调用draw_triangle(自身)来从当前线的中心画出新的、更小的三角形。然后,这将反过来打击同一个代码块,为一个更小的三角形计算另一组中心点和旋转。

    这就是所谓的循环算法,因为draw_triangle函数现在会调用自己,直到达到希望绘制的三角形的最大深度。有这个转义句子是很重要的,因为理论上这个函数会一直循环下去(但实际上调用堆栈会变得太大,导致堆栈溢出错误)。

    def draw_triangle(center, side_length, degrees_rotate, thickness, colour, \
                      pixels, shrink_side_by, iteration, max_depth):
        # 等边三角形的高度是,h = ½(√3a)
        # 其中'a'是边长
        triangle_height = side_length * math.sqrt(3)/2
        # 顶角
        top = [center[0] - triangle_height/2, center[1]]
        # 左下角
        bottom_left = [center[0] + triangle_height/2, center[1] - side_length/2]
        # 右下角
        bottom_right = [center[0] + triangle_height/2, center[1] + side_length/2]
        if (degrees_rotate != 0):
            top = rotate(top, center, degrees_rotate)
            bottom_left = rotate(bottom_left, center, degrees_rotate)
            bottom_right = rotate(bottom_right, center, degrees_rotate)
        # 三角形各边之间的坐标
        lines = [[top, bottom_left],[top, bottom_right],[bottom_left, bottom_right]]
        line_number = 0
        # 在每个角之间画一条线来完成三角形
        for line in lines:
            line_number += 1
            plot_line(line[0], line[1], thickness, colour, pixels)
            # 如果还没有达到max_depth,就画一些新的三角形
            if (iteration < max_depth and (iteration < 1 or line_number < 3)):
                gradient = (line[1][0] - line[0][0]) / (line[1][1] - line[0][1])
                new_side_length = side_length*shrink_side_by
                # 正在绘制的三角形线的中心
                center_of_line = [(line[0][0] + line[1][0]) / 2, \
                                  (line[0][1] + line[1][1]) / 2]
                new_center = []
                new_rotation = degrees_rotate
                # 需要旋转traingle的数量
                if (line_number == 1):
                    new_rotation += 60
                elif (line_number == 2):
                    new_rotation -= 60
                else:
                    new_rotation += 180
                # 在一个理想的世界里,这将是gradient=0,
                # 但由于浮点除法的原因,无法
                # 确保永远是这种情况
                if (gradient < 0.0001 and gradient > -0.0001):
                    if (center_of_line[0] - center[0] > 0):
                        new_center = [center_of_line[0] + triangle_height * \
                                     (shrink_side_by/2), center_of_line[1]]
                    else:
                        new_center = [center_of_line[0] - triangle_height * \
                                      (shrink_side_by/2), center_of_line[1]]
                else:
                    # 计算直线梯度的法线
                    difference_from_center = -1/gradient
                    # 计算这条线距中心的距离
                    # 到新三角形的中心
                    distance_from_center = triangle_height * (shrink_side_by/2)
                    # 计算 x 方向的长度,
                    # 从线的中心到新三角形的中心
                    x_length = math.sqrt((distance_from_center**2)/ \
                                         (1 + difference_from_center**2))
                    # 计算出x方向需要走哪条路
                    if (center_of_line[1] < center[1] and x_length > 0):
                        x_length *= -1
                    # 现在计算Y方向的长度
                    y_length = x_length * difference_from_center
                    # 用新的x和y值来偏移线的中心
                    new_center = [center_of_line[0] + y_length, \
                                  center_of_line[1] + x_length]
                draw_triangle(new_center, new_side_length, new_rotation, \
                              thickness, colour, pixels, shrink_side_by, \
                              iteration+1, max_depth)

    如何使用Python绘制分形图案?

    三角形分形,收缩边=1/2,最大深度=2

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python
    相关文章 更多
    python删除一个列表里的重复元素的方法与代码示例
    python删除一个列表里的重复元素的方法与代码示例

    学习如何使用Python高效删除列表中的重复元素。本文提供5种常见方法的代码示例,涵盖保持顺序与不保持顺序的场景,适合初学者和进阶开发者参考。

    Python写接口的步骤及完整代码示例
    Python写接口的步骤及完整代码示例

    详细讲解使用Python编写Web接口的核心步骤与完整代码示例,涵盖环境准备、路由定义、数据校验、服务启动及调试测试方法。

    codex怎么读取word文档及docx文件操作教程
    codex怎么读取word文档及docx文件操作教程

    介绍如何利用编程工具读取和解析Word文档(docx格式),涵盖基础文本提取代码示例、结构化数据处理逻辑,以及处理复杂排版时的技术局限与替代方案。

    怎么在Python中调用C语言代码提升性能
    怎么在Python中调用C语言代码提升性能

    详细讲解在Python中调用C语言代码提升性能的完整实践指南,包含原理分析、编译步骤、ctypes与CFFI具体实现、性能对比及常见陷阱。

    Python与C语言的性能差异及底层原理
    Python与C语言的性能差异及底层原理

    深入解析Python与C语言在执行效率上的数量级差异,从编译机制、变量内存布局、动态类型推断到GIL锁,系统阐明底层核心原理。

    Python和C语言哪个更适合编程入门
    Python和C语言哪个更适合编程入门

    客观对比Python与C语言在心智负担、底层机制与学习反馈上的核心差异,提供清晰有据的选择标准与切实的入门学习路径。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    langgraph python guide中文入门教程详解
    langgraph python guide中文入门教程详解

    本篇LangGraph Python中文入门教程详解,系统梳理StateGraph状态机定义、节点编写、边与条件路由、检查点持久化(MemorySaver)等核心机制,提供从环境安装到完整循环智能体构建的代码示例与实操指导。

    Windows 安装 Python:从官方入口到虚拟环境的可复现实践
    Windows 安装 Python:从官方入口到虚拟环境的可复现实践

    面向后端开发者,基于 Python 官方文档说明如何在 Windows 上安装 Python、创建 venv 虚拟环境及使用 pip 管理依赖。包含可复制命令、验证方法及工具选择边界,避免常见配置误区。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。