为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常用的日期时间处理方法示例
Feb 08 Python
Python如何读取MySQL数据库表数据
Mar 11 Python
利用python获取当前日期前后N天或N月日期的方法示例
Jul 30 Python
django rest framework之请求与响应(详解)
Nov 06 Python
python pycurl验证basic和digest认证的方法
May 02 Python
Python闭包函数定义与用法分析
Jul 20 Python
python实现归并排序算法
Nov 22 Python
Python简易版图书管理系统
Aug 12 Python
python并发编程 Process对象的其他属性方法join方法详解
Aug 20 Python
Python加密模块的hashlib,hmac模块使用解析
Jan 02 Python
python3.9实现pyinstaller打包python文件成exe
Dec 13 Python
python中altair可视化库实例用法
Jan 26 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相当简单的分页类
2008/10/02 PHP
非常好用的两个PHP函数 serialize()和unserialize()
2012/02/04 PHP
php版微信自动获取收货地址api用法示例
2016/09/22 PHP
PHP中的empty、isset、isnull的区别与使用实例
2019/03/22 PHP
php版本CKEditor 4和CKFinder安装及配置方法图文教程
2019/06/05 PHP
jQuery 处理表单元素的代码
2010/02/15 Javascript
javascript 学习笔记(一)DOM基本操作
2011/04/08 Javascript
使用JavaScript动态设置样式实现代码及演示动画
2013/01/25 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
2013/06/27 Javascript
jquery each的几种常用的使用方法示例
2014/01/21 Javascript
jQuery事件用法实例汇总
2014/08/29 Javascript
JavaScript函数作用域链分析
2015/02/13 Javascript
Jquery实现textarea根据文本内容自适应高度
2015/04/03 Javascript
JS/jQ实现免费获取手机验证码倒计时效果
2016/06/13 Javascript
jquery 获取select数组与name数组长度的实现代码
2016/06/20 Javascript
jquery中用jsonp实现搜索框功能
2016/10/18 Javascript
JS实现重新加载当前页面
2016/11/29 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
微信小程序登录session的使用
2019/03/17 Javascript
vue指令v-html使用过滤器filters功能实例
2019/10/25 Javascript
[02:53]DOTA2亚洲邀请赛 NewBee战队巡礼
2015/02/03 DOTA
[01:34]DAC2018主赛事第四日五佳镜头 Gh巨牙海民助Miracle-死里逃生
2018/04/07 DOTA
判断网页编码的方法python版
2016/08/12 Python
python交互式图形编程实例(二)
2017/11/17 Python
基于Python中numpy数组的合并实例讲解
2018/04/04 Python
详解django的serializer序列化model几种方法
2018/10/16 Python
Python中pyecharts安装及安装失败的解决方法
2020/02/18 Python
canvas实现漂亮的下雨效果的示例
2018/04/18 HTML / CSS
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
lookfantastic荷兰:在线购买奢华护肤、护发和化妆品
2018/11/27 全球购物
JSP&Servlet技术面试题
2015/05/21 面试题
医院后勤自我鉴定
2013/10/13 职场文书
保险公司早会主持词
2014/03/22 职场文书
工作会议方案
2014/05/21 职场文书
师德自我剖析材料范文
2014/10/06 职场文书
会计工作岗位职责
2015/02/03 职场文书