Matplotlib 3D 绘制小红花原理
作者:夏小悠 发布时间:2022-11-23 11:53:08
前言:
在上篇博文中使用了matplotlib
绘制了3D小红花,本篇博客主要介绍一下3D小红花的绘制原理。
1. 极坐标系
对于极坐标系中的一点 P ,我们可以用极径 r 和极角 θ 来表示,记为点 P ( r , θ ) ,
使用matplotlib绘制极坐标系:
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
# 极径
r = np.arange(10)
# 角度
theta = 0.5 * np.pi * r
fig = plt.figure()
plt.polar(theta, r, c='r', marker='o', ms=3, ls='-', lw=1)
# plt.savefig('img/polar1.png')
plt.show()
使用matplotlib绘制极坐标散点图:
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
r = np.linspace(0, 10, num=10)
theta = 2 * np.pi * r
area = 3 * r ** 2
ax = plt.subplot(111, projection='polar')
ax.scatter(theta, r, c=theta, s=area, cmap='hsv', alpha=0.75)
# plt.savefig('img/polar2.png')
plt.show()
有关matplotlib
极坐标的参数更多介绍,可参阅官网手册。
2. 极坐标系花瓣
绘制r = s i n ( θ ) r=sin(\theta)r=sin(θ)
在极坐标系下的图像:
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
fig = plt.figure()
ax = plt.subplot(111, projection='polar')
ax.set_rgrids(radii=np.linspace(-1, 1, num=5), labels='')
theta = np.linspace(0, 2 * np.pi, num=200)
r = np.sin(theta)
ax.plot(theta, r)
# plt.savefig('img/polar3.png')
plt.show()
以 2 π 为一个周期,增加图像的旋转周期:
r = np.sin(2 * theta)
继续增加图像的旋转周期:
r = np.sin(3 * theta)
r = np.sin(4 * theta)
然后我们可以通过调整极径系数和角度系数来调整图像:
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
fig = plt.figure()
ax = plt.subplot(111, projection='polar')
ax.set_rgrids(radii=np.linspace(-1, 1, num=5), labels='')
theta = np.linspace(0, 2 * np.pi, num=200)
r1 = np.sin(4 * (theta + np.pi / 8))
r2 = 0.5 * np.sin(5 * theta)
r3 = 2 * np.sin(6 * (theta + np.pi / 12))
ax.plot(theta, r1)
ax.plot(theta, r2)
ax.plot(theta, r3)
# plt.savefig('img/polar4.png')
plt.show()
3. 三维花瓣
现在可以将花瓣放置在三维空间上了,根据花瓣的生成规律,其花瓣外边缘线在一条旋转内缩的曲线上,这条曲线的极径 r 随着角度的增大逐渐变小,其高度 h 逐渐变大。
其函数图像如下:
这样定义就满足前面对花瓣外边缘曲线的假设了,即 r 递减, h 递增。
现在将其放在三维空间中:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
if __name__ == '__main__':
fig = plt.figure()
ax = Axes3D(fig)
# plt.axis('off')
x = np.linspace(0, 1, num=30)
theta = np.linspace(0, 2 * np.pi, num=1200)
theta = 30 * theta
x, theta = np.meshgrid(x, theta)
# f is a decreasing function of theta
f = 0.5 * np.pi * np.exp(-theta / 50)
r = x * np.sin(f)
h = x * np.cos(f)
# 极坐标转笛卡尔坐标
X = r * np.cos(theta)
Y = r * np.sin(theta)
ax = ax.plot_surface(X, Y, h,
rstride=1, cstride=1, cmap=plt.cm.cool)
# plt.savefig('img/polar5.png')
plt.show()
笛卡尔坐标系(Cartesian coordinate system)
,即直角坐标系。
然而,上述的表达仍然没有得到花瓣的细节,因此我们需要在此基础之上进行处理,以得到花瓣形状。因此设计了一个花瓣函数:
其是一个以 2 π 为周期的周期函数,其值域为[ 0.5 , 1.0 ],图像如下图所示:
再次绘制:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
if __name__ == '__main__':
fig = plt.figure()
ax = Axes3D(fig)
# plt.axis('off')
x = np.linspace(0, 1, num=30)
theta = np.linspace(0, 2 * np.pi, num=1200)
theta = 30 * theta
x, theta = np.meshgrid(x, theta)
# f is a decreasing function of theta
f = 0.5 * np.pi * np.exp(-theta / 50)
# 通过改变函数周期来改变花瓣的形状
# 改变值域也可以改变花瓣形状
# u is a periodic function
u = 1 - (1 - np.absolute(np.sin(3.3 * theta / 2))) / 2
r = x * u * np.sin(f)
h = x * u * np.cos(f)
# 极坐标转笛卡尔坐标
X = r * np.cos(theta)
Y = r * np.sin(theta)
ax = ax.plot_surface(X, Y, h,
rstride=1, cstride=1, cmap=plt.cm.RdPu_r)
# plt.savefig('img/polar6.png')
plt.show()
4. 花瓣微调
  为了使花瓣更加真实,使花瓣的形态向下凹,因此需要对花瓣的形状进行微调,这里添加一个修正项和一个噪声扰动,修正函数图像为:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
if __name__ == '__main__':
fig = plt.figure()
ax = Axes3D(fig)
# plt.axis('off')
x = np.linspace(0, 1, num=30)
theta = np.linspace(0, 2 * np.pi, num=1200)
theta = 30 * theta
x, theta = np.meshgrid(x, theta)
# f is a decreasing function of theta
f = 0.5 * np.pi * np.exp(-theta / 50)
noise = np.sin(theta) / 30
# u is a periodic function
u = 1 - (1 - np.absolute(np.sin(3.3 * theta / 2))) / 2 + noise
# y is a correction function
y = 2 * (x ** 2 - x) ** 2 * np.sin(f)
r = u * (x * np.sin(f) + y * np.cos(f))
h = u * (x * np.cos(f) - y * np.sin(f))
X = r * np.cos(theta)
Y = r * np.sin(theta)
ax = ax.plot_surface(X, Y, h,
rstride=1, cstride=1, cmap=plt.cm.RdPu_r)
# plt.savefig('img/polar7.png')
plt.show()
修正前后图像区别对比如下:
5. 结束语
3D花的绘制主要原理是极坐标,通过正弦/余弦函数进行旋转变形构造,参数略微变化就会出现不同的花朵,有趣!
来源:https://blog.csdn.net/qq_42730750/article/details/122940228


猜你喜欢
- pycharm是一款高效的python IDE工具,它非常强大,且可以跨平台,是新手首选工具!下面我给第一次使用这款软件的朋友做一个简单的使
- 方式一import matplotlib.pyplot as pltimport numpy as npfrom scipy.stats i
- 前言前段时间,因为项目需求,需要根据关键词搜索聊天记录,这不就是一个搜索引擎的功能吗?于是我第一时间想到的就是 ElasticSearch
- 我就废话不多说了,直接上代码吧:package mainimport ("flag""fmt"&qu
- 需求: 一台机器上有多个网卡, 如何访问指定的 URL 时使用指定的网卡发送数据呢?$ curl --interface eth0 www.
- 1.1.1 摘要 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接、外联接和交叉联接等。如果我们想
- 一、 操作数据库(mysql)的工具1.1命令行工具1.2navicat界面化工具1.3phpAdmin界面化工具一般情况下安装phpstu
- Seconds_Behind_Master对于mysql主备实例,seconds_behind_master是衡量master与slave之
- 1.简介 蒙特卡洛又称随机抽样或统计试验,就是
- 一、os模块os 模块是 Python中的一个内置模块,也是 Python中整理文件和目录最为常用的模块。该模块提供了非常丰富的方法用来处理
- 一、pycharm配置1、部署配置工具==》部署==》配置2、python解释器文件==》设置==》项目:xx==》python解释器3、运
- 一、概述PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却
- 本文以实例形式较为详细的讲解了Python的多线程,是Python程序设计中非常重要的知识点。分享给大家供大家参考之用。具体方法如下:用过P
- 在这个擦亮自己的眼睛去看SQL Server的系列中的第二篇中提过要写历史渊源,这里的历史主要描述的是数据库本身的历史与SQL Server
- 译序:本文译自Smashingmagazine,但是原文讲述的内容有些浅,也不是很完整,前端观察在翻译的前提下,增加了更多的更系统的内容。如
- 整体思路将要备份的目录列为一个列表,通过执行系统命令,进行压缩、备份。这样关键在于构造命令并使用 os.system( )来执行,一开始使用
- 前言:大家都知道在java 开发过程中,会经常用到锁,在java 代码中,我们都知道锁是加在对象头上的,在java对象布局中有锁的标志位。程
- 本文实例讲述了php实现mysql事务处理的方法。分享给大家供大家参考。具体分析如下:要实现本功能的条件是环境 mysql 5.2 /php
- 去过新浪或者搜狐吗?虽然我们都不愿意看广告,但是它们做广告的技术我们却应该学到手,这不,又一种很流行的做法儿,做成那种两边对称的对联式的广告
- 哎,好久没有学习爬虫了,现在想要重新拾起来。发现之前学习爬虫有些粗糙,竟然连requests中添加cookies都没有掌握,惭愧。废话不宜多