0


Matplotlib 3D小红花的绘制原理

文章目录

前言

  在上篇博客中使用了

  1. matplotlib

绘制了3D小红花,本篇博客主要介绍一下3D小红花的绘制原理。

1. 极坐标系

  对于极坐标系中的一点

  1. P
  2. P
  3. P,我们可以用极径
  4. r
  5. r
  6. r 和极角
  7. θ
  8. \theta
  9. θ 来表示,记为点
  10. P
  11. (
  12. r
  13. ,
  14. θ
  15. )
  16. P(r, \theta)
  17. P(r,θ),其相关知识在高中就已经介绍,这里不再赘述。

  使用

  1. matplotlib

绘制极坐标系:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. if __name__ =='__main__':# 极径
  4. r = np.arange(10)# 角度
  5. theta =0.5* np.pi * r
  6. fig = plt.figure()
  7. plt.polar(theta, r, c='r', marker='o', ms=3, ls='-', lw=1)# plt.savefig('img/polar1.png')
  8. plt.show()

在这里插入图片描述
  使用

  1. matplotlib

绘制极坐标散点图:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. if __name__ =='__main__':
  4. r = np.linspace(0,10, num=10)
  5. theta =2* np.pi * r
  6. area =3* r **2
  7. ax = plt.subplot(111, projection='polar')
  8. ax.scatter(theta, r, c=theta, s=area, cmap='hsv', alpha=0.75)# plt.savefig('img/polar2.png')
  9. plt.show()

在这里插入图片描述

  有关

  1. matplotlib

极坐标的参数更多介绍,可参阅官网手册。

2. 极坐标系花瓣

  绘制

  1. r
  2. =
  3. s
  4. i
  5. n
  6. (
  7. θ
  8. )
  9. r=sin(\theta)
  10. r=sin(θ) 在极坐标系下的图像:
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. if __name__ =='__main__':
  4. fig = plt.figure()
  5. ax = plt.subplot(111, projection='polar')
  6. ax.set_rgrids(radii=np.linspace(-1,1, num=5), labels='')
  7. theta = np.linspace(0,2* np.pi, num=200)
  8. r = np.sin(theta)
  9. ax.plot(theta, r)# plt.savefig('img/polar3.png')
  10. plt.show()

在这里插入图片描述
  以

  1. 2
  2. π
  3. 2\pi
  4. 2π 为一个周期,增加图像的旋转周期:
  1. r = np.sin(2* theta)

在这里插入图片描述
  继续增加图像的旋转周期:

  1. r = np.sin(3* theta)
  2. r = np.sin(4* theta)


  然后我们可以通过调整极径系数和角度系数来调整图像:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. if __name__ =='__main__':
  4. fig = plt.figure()
  5. ax = plt.subplot(111, projection='polar')
  6. ax.set_rgrids(radii=np.linspace(-1,1, num=5), labels='')
  7. theta = np.linspace(0,2* np.pi, num=200)
  8. r1 = np.sin(4*(theta + np.pi /8))
  9. r2 =0.5* np.sin(5* theta)
  10. r3 =2* np.sin(6*(theta + np.pi /12))
  11. ax.plot(theta, r1)
  12. ax.plot(theta, r2)
  13. ax.plot(theta, r3)# plt.savefig('img/polar4.png')
  14. plt.show()

在这里插入图片描述

3. 三维花瓣

  现在可以将花瓣放置在三维空间上了,根据花瓣的生成规律,其花瓣外边缘线在一条旋转内缩的曲线上,这条曲线的极径

  1. r
  2. r
  3. r 随着角度的增大逐渐变小,其高度
  4. h
  5. h
  6. h 逐渐变大。

  因此我们在

  1. f
  2. (
  3. x
  4. )
  5. =
  6. e
  7. x
  8. f(x) = e^{-x}
  9. f(x)=ex 的基础之上定义了一个递减函数,保证其值域在
  10. (
  11. 0
  12. ,
  13. π
  14. 2
  15. ]
  16. (0, \frac {\pi} {2}]
  17. (0,2π​],新的函数为:
  18. f
  19. (
  20. θ
  21. )
  22. =
  23. π
  24. 2
  25. e
  26. θ
  27. f(\theta)=\frac {\pi} {2} e^{-\theta}
  28. f(θ)=2π​e−θ  其函数图像如下:![在这里插入图片描述](https://img-blog.csdnimg.cn/79b6596d280544a695fe3ba3367a52b4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5aSP5bCP5oKg,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)

  这样定义

  1. r
  2. =
  3. s
  4. i
  5. n
  6. (
  7. f
  8. )
  9. ,
  10. h
  11. =
  12. c
  13. o
  14. s
  15. (
  16. f
  17. )
  18. r=sin(f), h=cos(f)
  19. r=sin(f),h=cos(f) 就满足前面对花瓣外边缘曲线的假设了,即
  20. r
  21. r
  22. r 递减,
  23. h
  24. h
  25. h 递增。

  现在将其放在三维空间中:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from mpl_toolkits.mplot3d import Axes3D
  4. if __name__ =='__main__':
  5. fig = plt.figure()
  6. ax = Axes3D(fig)# plt.axis('off')
  7. x = np.linspace(0,1, num=30)
  8. theta = np.linspace(0,2* np.pi, num=1200)
  9. theta =30* theta
  10. x, theta = np.meshgrid(x, theta)# f is a decreasing function of theta
  11. f =0.5* np.pi * np.exp(-theta /50)
  12. r = x * np.sin(f)
  13. h = x * np.cos(f)# 极坐标转笛卡尔坐标
  14. X = r * np.cos(theta)
  15. Y = r * np.sin(theta)
  16. ax = ax.plot_surface(X, Y, h,
  17. rstride=1, cstride=1, cmap=plt.cm.cool)# plt.savefig('img/polar5.png')
  18. plt.show()

在这里插入图片描述

  笛卡尔坐标系

  1. (Cartesian coordinate system)

,即直角坐标系。

  然而,上述的表达仍然没有得到花瓣的细节,因此我们需要在此基础之上进行处理,以得到花瓣形状。因此设计了一个花瓣函数:

  1. f
  2. (
  3. θ
  4. )
  5. =
  6. 1
  7. 1
  8. s
  9. i
  10. n
  11. (
  12. θ
  13. 2
  14. )
  15. 2
  16. f(\theta) = 1 - \frac {1 - |sin(\frac {\theta} {2})|} {2}
  17. f(θ)=121−∣sin(2θ​)∣​  其是一个以
  18. 2
  19. π
  20. 2\pi
  21. 2π 为周期的周期函数,其值域为
  22. [
  23. 0.5
  24. ,
  25. 1.0
  26. ]
  27. [0.5, 1.0]
  28. [0.5,1.0],图像如下图所示:

在这里插入图片描述
  再次绘制:

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from mpl_toolkits.mplot3d import Axes3D
  4. if __name__ =='__main__':
  5. fig = plt.figure()
  6. ax = Axes3D(fig)# plt.axis('off')
  7. x = np.linspace(0,1, num=30)
  8. theta = np.linspace(0,2* np.pi, num=1200)
  9. theta =30* theta
  10. x, theta = np.meshgrid(x, theta)# f is a decreasing function of theta
  11. f =0.5* np.pi * np.exp(-theta /50)# 通过改变函数周期来改变花瓣的形状# 改变值域也可以改变花瓣形状# u is a periodic function
  12. u =1-(1- np.absolute(np.sin(3.3* theta /2)))/2
  13. r = x * u * np.sin(f)
  14. h = x * u * np.cos(f)# 极坐标转笛卡尔坐标
  15. X = r * np.cos(theta)
  16. Y = r * np.sin(theta)
  17. ax = ax.plot_surface(X, Y, h,
  18. rstride=1, cstride=1, cmap=plt.cm.RdPu_r)# plt.savefig('img/polar6.png')
  19. plt.show()

在这里插入图片描述
在这里插入图片描述

4. 花瓣微调

  为了使花瓣更加真实,使花瓣的形态向下凹,因此需要对花瓣的形状进行微调,这里添加一个修正项和一个噪声扰动,修正函数图像为:
在这里插入图片描述

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from mpl_toolkits.mplot3d import Axes3D
  4. if __name__ =='__main__':
  5. fig = plt.figure()
  6. ax = Axes3D(fig)# plt.axis('off')
  7. x = np.linspace(0,1, num=30)
  8. theta = np.linspace(0,2* np.pi, num=1200)
  9. theta =30* theta
  10. x, theta = np.meshgrid(x, theta)# f is a decreasing function of theta
  11. f =0.5* np.pi * np.exp(-theta /50)
  12. noise = np.sin(theta)/30# u is a periodic function
  13. u =1-(1- np.absolute(np.sin(3.3* theta /2)))/2+ noise
  14. # y is a correction function
  15. y =2*(x **2- x)**2* np.sin(f)
  16. r = u *(x * np.sin(f)+ y * np.cos(f))
  17. h = u *(x * np.cos(f)- y * np.sin(f))
  18. X = r * np.cos(theta)
  19. Y = r * np.sin(theta)
  20. ax = ax.plot_surface(X, Y, h,
  21. rstride=1, cstride=1, cmap=plt.cm.RdPu_r)# plt.savefig('img/polar7.png')
  22. plt.show()

在这里插入图片描述
  修正前后图像区别对比如下:
在这里插入图片描述

5. 结束语

  1. 3D

花的绘制主要原理是极坐标,通过正弦/余弦函数进行旋转变形构造,参数略微变化就会出现不同的花朵,有趣!

在这里插入图片描述


本文转载自: https://blog.csdn.net/qq_42730750/article/details/122940228
版权归原作者 夏小悠 所有, 如有侵权,请联系我们删除。

“Matplotlib 3D小红花的绘制原理”的评论:

还没有评论