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
猜你喜欢
- 前言pytest.mark.skip可以标记无法在某些平台上运行的测试功能,或者您希望失败的测试功能希望满足某些条件才执行某些测试用例,否则
- global.asa<SCRIPT LANGUAGE=VBScript RUNAT=Server>Sub&n
- --------------------------------------------------------- 正则收藏 手机号码: $
- 你喜欢在博客文章中使用图片吗?是的,如果不是很麻烦的话,相信大家都不会介意放上几张漂亮的图片来点缀一下内容的,不过你的图片可能会导致下面的两
- ASP编写完整的一个IP所在地搜索类的修正文稿修正了查询方法,查询的方法和追捕的一致;只是追捕会自动更正IP。还有个函数的书写错误,也已经修
- 前言本文做的是基于三层神经网络实现手写数字分类,神经网络设计是设计复杂深度学习算法应用的基础,本文将介绍如何设计一个三层神经网络模型来实现手
- 前三篇文章中,明确了栅格系统的设计细节和适用范围。这一篇将集中讨论960栅格系统的技术实现。Blueprint的实现Blueprint是一个
- 一个动态数组 a,如果你已经使用redim 语句给它设定了大小,那么在此之后使用 ubound(a) 就可以得到它的上边界。如果你没有使用
- 起步Pandas最初被作为金融数据分析工具而开发出来,因此 pandas 为时间序列分析提供了很好的支持。 Pandas 的名称来自于面板数
- 你们要的3D太阳系图片上传之后不知为何帧率降低了许多。。。日地月三体所谓三体,就是三个物体在重力作用下的运动。由于三点共面,所以三个质点仅在
- 众所周知,随着数据库体积的日益庞大,其备份文件的大小也水涨船高。虽然说通过差异备份与完全备份配套策略,可以大大的减小SQL Server数据
- 前言现在正是卡塔尔世界杯激战正酣的时候,每天都有各种各样的新闻。而且,不同的球队,随着比赛的进程,关注的热度也会发生翻天覆地的变化。今天我们
- 如下所示:#!/usr/bin/python#coding:utf-8import MySQLdbimport time,datetime#
- quiver绘制表示梯度变化非常有用,下面是学习过程中给出的两个例子,可以很好理解quiver的用法from pylab import *c
- 实验环境:windows 7,anaconda 3(Python 3.5),tensorflow(gpu/cpu)函数介绍:标准化处理可以使
- 先说说线程在多线程中,为了保证共享资源的正确性,我们常常会用到线程同步技术.将一些敏感操作变成原子操作,保证同一时刻多个线程中只有一个线程在
- Python 链接抖音python下载抖音内容的帖子网上有一些,但都比较麻烦,需要通过adb连接安卓手机后,模拟操作。我这么懒,这种事儿玩不
- 1.11 – 添加缎带修饰网页局部模块中右上角的蓝色缎带修饰是这个网站界面设计中的一个亮点,只要合理的运用CSS、PNG透明图片和绝对定位属
- 最近遇到一个问题,就是获取表单中的日期往后台通过json方式传的时候,遇到Date.parse(str)函数在ff下报错: NAN 找了些资
- html页面一般都会指定一个编码,如何获取到是处理html页面的第一步,因为错误的编码必然带来后面处理的问题。这里我用python的正则表达