为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景


Posted in Python onJanuary 05, 2021

一场大雪,覆盖了华北、华东。天地连成一片,城市银装素裹,处处诗情画意、人人兴高采烈。朋友圈被雪景图和调侃路滑摔跤的段子刷屏,气氛比过年还要热烈几分。我也来凑个热闹,用python为2020年的第一场雪锦上添花。

绘制雪花图案,网上有很多文章介绍,但几乎都是用 Python 的内置模块 turtle 绘制的,这个模块适合用来引导孩子学习编程,很难真正用在项目开发上。也有用 pygame 实现的,不过 pygame 追求的是动画效果,雪花图案是随机生成的圆,效果很一般。

用 matplotlib 绘制雪花,重点是生成科赫曲线(Koch Curve)。科赫曲线是一种分形,其形态似雪花,又称科赫雪花、雪花曲线。给定线段pq,k阶科赫曲线可以由以下步骤生成:

  • 找出三等分点u、v
  • 以线段uv为底,向外(或内外)画等边三角形uwv
  • 将线段uv移除
  • 对pq之间的每一段重复上述操作k-1次

科赫雪花是以等边三角形三边生成的科赫曲线组成的。基于上述分析,我们可以很容易地写出科赫雪花的生成函数:给定一个等边三角形,和科赫曲线阶数k,返回科赫雪花图案中的所有点。

import numpy as np

plt.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False #解决中文显示为方块的问题

def rotate(p, d):
  """返回点p绕原点逆时针旋转d度的坐标"""
  
  a = np.radians(d)
  m = np.array([[np.cos(a), np.sin(a)],[-np.sin(a), np.cos(a)]])
  return np.dot(p, m)

def koch_curve(p, q):
  """将线段pq生成科赫曲线,返回uvw三个点"""
  
  p, q = np.array(p), np.array(q)
  u = p + (q-p)/3 # 三等分点u的坐标
  v = q - (q-p)/3 # 三等分点V的坐标
  w = rotate(v-u, 60) + u # 线段uv绕u点逆时针旋转60°得到点w的坐标
  
  return u.tolist(), v.tolist(), w.tolist()
  
def snow(triangle, k):
  """给定三角形,生成封闭的科赫雪花"""
  
  for i in range(k):
    result = list()
    t_len = len(triangle)
    for j in range(t_len):
      p = triangle[j]
      q = triangle[(j+1)%t_len]
      u, v, w = koch_curve(p, q)
      result.extend([p, u, w, v])
    triangle = result.copy()
  
  triangle.append(triangle[0])
  return triangle

有了雪花图案的数据,接下来使用 matplotlib 绘图就非常轻松了:

import numpy as np
import matplotlib.pyplot as plt

def plot_snow(snow_list):
  """绘制雪花"""
  
  for triangle, k in snow_list:
    data = np.array(snow(triangle, k))
    x, y = np.split(data, 2, axis=1)
    plt.plot(x, y)
  
  plt.axis('equal') 
  plt.show()

snow_list = [
  ([(0,0), (0.5,0.8660254), (1,0)], 5),
  ([(1.1,0.4), (1.35,0.8330127), (1.6,0.4)], 4),
  ([(1.1,-0.1), (1.25,0.15980761), (1.4,-0.1)], 3)
]
plot_snow(snow_list)

来看看我们的雪花效果。从小到大,3片雪花分别对应的是3阶、4阶、5阶的科赫雪花。

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

更进一步,我们还可以把雪花画在背景图上,配合大小浓淡的变化,画出另一种韵味的雪景图。

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

def draw_scenery():
  """绘制雪景图"""
  
  im = Image.open('brage.png')
  bg = np.array(im)
  plt.imshow(bg) # 绘制背景图
  
  for i in range(80):
    x = np.random.randint(80, im.size[0]-80)
    y = np.random.randint(30, im.size[1]-30)
    r = np.random.randint(5, 20)
    a = np.random.random()*0.6 + 0.2
    v = np.array((x-r/2, y))
    u = np.array((x+r/2, y))
    w = rotate(v-u, 60) + u
    
    data = np.array(snow([(u[0],u[1]),(w[0],w[1]),(v[0],v[1])], 5))
    x, y = np.split(data, 2, axis=1)
    plt.plot(x, y, c='#AABBCC', lw=1, ls='-', alpha=a)
  
  plt.axis('equal') 
  plt.show()

draw_scenery()

为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景

到此这篇关于为2021年的第一场雪锦上添花:用matplotlib绘制雪花和雪景的文章就介绍到这了,更多相关matplotlib绘制雪花和雪景内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python函数参数*args**kwargs用法实例
Dec 04 Python
python下如何查询CS反恐精英的服务器信息
Jan 17 Python
Python批量合并有合并单元格的Excel文件详解
Apr 05 Python
Python3中编码与解码之Unicode与bytes的讲解
Feb 28 Python
python 堆和优先队列的使用详解
Mar 05 Python
通过cmd进入python的实例操作
Jun 26 Python
python创建学生管理系统
Nov 22 Python
Django数据结果集序列化并展示实现过程
Apr 22 Python
Django Path转换器自定义及正则代码实例
May 29 Python
Matplotlib自定义坐标轴刻度的实现示例
Jun 18 Python
Python3交互式shell ipython3安装及使用详解
Jul 11 Python
Python超简单容易上手的画图工具库推荐
May 10 Python
Matplotlib中rcParams使用方法
Jan 05 #Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
Jan 05 #Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
Jan 05 #Python
matplotlib制作雷达图报错ValueError的实现
Jan 05 #Python
python实现三种随机请求头方式
Jan 05 #Python
scrapy实践之翻页爬取的实现
Jan 05 #Python
python里glob模块知识点总结
Jan 05 #Python
You might like
php使用正则表达式获取图片url的方法
2015/01/16 PHP
PHP+jQuery+Ajax实现分页效果 jPaginate插件的应用
2015/10/09 PHP
使用PHPUnit进行单元测试并生成代码覆盖率报告的方法
2019/03/08 PHP
PHP判断当前使用的是什么浏览器(推荐)
2019/10/27 PHP
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
jquery 判断div show的状态实例
2016/12/03 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
BootStrap的两种模态框方式
2017/05/10 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
vue项目中使用fetch的实现方法
2019/04/25 Javascript
解决layui使用layui-icon出现默认图标的问题
2019/09/11 Javascript
vue实现表格过滤功能
2019/09/27 Javascript
JavaScript将数组转换为链表的方法
2020/02/16 Javascript
[02:38]2018DOTA2亚洲邀请赛赛前采访-VGJ.T
2018/04/03 DOTA
python实现查询IP地址所在地
2015/03/29 Python
在Docker上部署Python的Flask框架的教程
2015/04/08 Python
浅谈python多线程和队列管理shell程序
2015/08/04 Python
详解Python中for循环是如何工作的
2017/06/30 Python
python正则表达式及使用正则表达式的例子
2018/01/22 Python
python中的global关键字的使用方法
2019/08/20 Python
tensorflow mnist 数据加载实现并画图效果
2020/02/05 Python
基于python3.7利用Motor来异步读写Mongodb提高效率(推荐)
2020/04/29 Python
Python try except finally资源回收的实现
2021/01/25 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
Beauty Expert美国/加拿大:购买奢侈美容产品
2018/12/05 全球购物
Java程序员面试题
2013/07/15 面试题
网络宣传方案
2014/03/15 职场文书
行政专员岗位职责说明书
2014/09/01 职场文书
个人委托书怎么写
2014/09/17 职场文书
2014学校领导四风对照检查材料思想汇报
2014/09/23 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
公司员工手册范本
2015/05/14 职场文书
带你了解Java中的ForkJoin
2022/04/28 Java/Android
SQL Server2019安装的详细步骤实战记录(亲测可用)
2022/06/10 SQL Server