为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错误处理详解
Sep 28 Python
python分析nignx访问日志脚本分享
Feb 26 Python
Python实现求最大公约数及判断素数的方法
May 26 Python
Python处理CSV与List的转换方法
Apr 19 Python
python3 线性回归验证方法
Jul 09 Python
python实现图片压缩代码实例
Aug 12 Python
django 连接数据库出现1045错误的解决方式
May 14 Python
python3将变量输入的简单实例
Aug 19 Python
基于python实现监听Rabbitmq系统日志代码示例
Nov 28 Python
详解Django关于StreamingHttpResponse与FileResponse文件下载的最优方法
Jan 07 Python
用Python自动清理电脑内重复文件,只要10行代码(自动脚本)
Jan 09 Python
Python编程根据字典列表相同键的值进行合并
Oct 05 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
apache rewrite_module模块使用教程
2008/01/10 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
php 使用GD库为页面增加水印示例代码
2014/03/24 PHP
Laravel5中contracts详解
2015/03/02 PHP
php的debug相关函数用法示例
2016/07/11 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
js调用图片隐藏&显示实现代码
2013/09/13 Javascript
node.js中的fs.chmod方法使用说明
2014/12/18 Javascript
js对象基础实例分析
2015/01/13 Javascript
使用Jquery实现每日签到功能
2015/04/03 Javascript
js控制div弹出层实现方法
2015/05/11 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
2015/08/09 Javascript
详解JavaScript逻辑And运算符
2015/12/04 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
select隐藏选中值对应的id,显示其它id的简单实现方法
2016/08/25 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
JS简单获取当前日期和农历日期的方法
2017/04/17 Javascript
javascript中mouseenter与mouseover的异同
2017/06/06 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
详解如何制作并发布一个vue的组件的npm包
2018/11/10 Javascript
Node.js创建一个Express服务的方法详解
2020/01/06 Javascript
vue 解决在微信内置浏览器中调用支付宝支付的情况
2020/11/09 Javascript
JavaScript实现筛选数组
2021/03/02 Javascript
Win7 64位下python3.6.5安装配置图文教程
2020/10/27 Python
AmazeUI 折叠面板的实现代码
2020/08/17 HTML / CSS
Java和Javasciprt的区别
2012/09/02 面试题
讲党性心得体会
2014/09/03 职场文书
四川省传达学习贯彻党的群众路线教育实践活动总结大会精神新闻稿
2014/10/26 职场文书
单位实习工作证明怎么写
2014/11/02 职场文书
教师党员群众路线教育实践活动心得体会
2014/11/04 职场文书
2014年老干部工作总结
2014/11/21 职场文书
2015年医院工作总结范文
2015/04/09 职场文书
企业爱心捐款倡议书
2015/04/27 职场文书
入党团支部推荐意见
2015/06/02 职场文书
爱国电影观后感
2015/06/19 职场文书
Redis高可用集群redis-cluster详解
2022/03/20 Redis