为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实现监控windows服务并自动启动服务示例
Apr 17 Python
Python使用py2exe打包程序介绍
Nov 20 Python
详解Python的Django框架中的模版继承
Jul 16 Python
利用Python自带PIL库扩展图片大小给图片加文字描述的方法示例
Aug 08 Python
Django 限制用户访问频率的中间件的实现
Aug 23 Python
python2和python3应该学哪个(python3.6与python3.7的选择)
Oct 01 Python
Django框架反向解析操作详解
Nov 28 Python
k-means 聚类算法与Python实现代码
Jun 01 Python
Python爬虫设置ip代理过程解析
Jul 20 Python
Python过滤序列元素的方法
Jul 31 Python
用Python监控你的朋友都在浏览哪些网站?
May 27 Python
利用python实时刷新基金估值(摸鱼小工具)
Sep 15 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定时执行计划任务的多种方法小结
2011/12/19 PHP
PHP三种方式实现链式操作详解
2017/01/21 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
Laravel框架实现简单的学生信息管理平台案例
2019/05/07 PHP
许愿墙中用到的函数
2006/10/07 Javascript
Prototype 学习 工具函数学习($w,$F方法)
2009/07/12 Javascript
javascript 模式设计之工厂模式学习心得
2010/04/27 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
JQuery中根据属性或属性值获得元素(6种情况获取方法)
2013/01/17 Javascript
Javascript玩转继承(一)
2014/05/08 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
在JavaScript中模拟类(class)及类的继承关系
2016/05/20 Javascript
Document.body.scrollTop的值总为零的快速解决办法
2016/06/09 Javascript
Bootstrap使用基础教程详解
2016/09/05 Javascript
Bootstrap CSS布局之表格
2016/12/17 Javascript
three.js实现3D视野缩放效果
2017/11/16 Javascript
基于JS实现父组件的请求服务过程解析
2019/10/14 Javascript
javascript实现搜索筛选功能实例代码
2020/11/12 Javascript
[13:56]DAC2018 4.5SOLO赛决赛 MidOne vs Paparazi第一场
2018/04/06 DOTA
python中numpy基础学习及进行数组和矢量计算
2017/02/12 Python
Python编写Windows Service服务程序
2018/01/04 Python
Python基于mysql实现学生管理系统
2019/02/21 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
python requests指定出口ip的例子
2019/07/25 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
2020/01/10 Python
MAC平台基于Python Appium环境搭建过程图解
2020/08/13 Python
英国最受欢迎的价格比较网站之一:MoneySuperMarket
2018/12/19 全球购物
大学生表扬信范文
2014/01/09 职场文书
民生工作实施方案
2014/05/31 职场文书
2014财务人员自我评价范文
2014/09/21 职场文书
党的群众路线教育实践活动领导班子整改方案
2014/10/25 职场文书
党员先进事迹材料
2014/12/19 职场文书
学前班语言教学计划
2015/01/20 职场文书
后勤个人工作总结
2015/02/28 职场文书
留学推荐信英文范文
2015/03/26 职场文书
Pygame Rect区域位置的使用(图文)
2021/11/17 Python