为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循环监控远程端口的方法
Mar 14 Python
解决Python传递中文参数的问题
Aug 04 Python
举例讲解Linux系统下Python调用系统Shell的方法
Nov 07 Python
python编写简单爬虫资料汇总
Mar 22 Python
python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)
Mar 12 Python
Python简单实现Base64编码和解码的方法
Apr 29 Python
Python使用functools实现注解同步方法
Feb 06 Python
对dataframe进行列相加,行相加的实例
Jun 08 Python
解决python ogr shp字段写入中文乱码的问题
Dec 31 Python
python实现nao机器人身体躯干和腿部动作操作
Apr 29 Python
Python内置数据类型list各方法的性能测试过程解析
Jan 07 Python
Python openpyxl 插入折线图实例
Apr 17 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
php2html php生成静态页函数
2008/12/08 PHP
php 按指定元素值去除数组元素的实现方法
2011/11/04 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
ubuntu下安装nodejs以及升级的办法
2015/05/08 NodeJs
JS使用正则表达式除去字符串中重复字符的方法
2015/11/05 Javascript
JavaScript学习笔记之取数组中最大值和最小值
2016/03/23 Javascript
AngularJS学习笔记之依赖注入详解
2016/05/16 Javascript
jQuery实现的checkbox级联选择下拉菜单效果示例
2016/12/26 Javascript
jQuery使用ajax_动力节点Java学院整理
2017/07/05 jQuery
javascript修改浏览器title方法 JS动态修改浏览器标题
2017/11/30 Javascript
vue 根据选择条件显示指定参数的例子
2019/11/09 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
[48:46]完美世界DOTA2联赛PWL S2 SZ vs FTD.C 第二场 11.19
2020/11/19 DOTA
python根据时间生成mongodb的ObjectId的方法
2015/03/13 Python
详解Python中内置的NotImplemented类型的用法
2015/03/31 Python
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
33个Python爬虫项目实战(推荐)
2019/07/08 Python
Python将视频或者动态图gif逐帧保存为图片的方法
2019/09/10 Python
使用python制作一个解压缩软件
2019/11/13 Python
Python字典dict常用方法函数实例
2020/11/09 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
2021/02/01 Python
python openpyxl模块的使用详解
2021/02/25 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
英国领先的男士美容护发用品公司:Mankind
2016/08/31 全球购物
opencv实现图像平移效果
2021/03/24 Python
美容师的职业规划书
2013/12/27 职场文书
优秀会计求职信
2014/07/04 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
医院护士见习期自我鉴定
2014/09/15 职场文书
同学聚会邀请函
2015/01/30 职场文书
陕西导游词
2015/02/04 职场文书
2016大学军训通讯稿
2015/11/25 职场文书
七年级作文之《我和我的祖国》观后感作文
2019/10/18 职场文书
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android
python区块链实现简版工作量证明
2022/05/25 Python