Educoder Matplotlib和Seaborn三维图 第2关:曲面三角剖分

第2关:曲面三角剖分 


任务描述

本关任务:编写一个能绘制三维曲面的程序。

相关知识

为了完成本关任务,你需要掌握:1.如何三角剖分图形;2.绘制莫比乌斯带。

  • 适用场景:立体图视觉上层次分明色彩鲜艳,具有很强的视觉冲击力,让观看的人驻景时间长,留下深刻的印象。

曲面三角剖分

在某些应用的场景中,之前那些些要求均匀采样的网格数据显得太过严格且不太容易实现。这时就可以使用三角剖分图形了。

 
  1. def f(x, y):
  2. return np.sin(np.sqrt(x ** 2 + y ** 2))
  3. theta = 2 * np.pi * np.random.random(1000)
  4. r = 6 * np.random.random(1000)
  5. x = np.ravel(r * np.sin(theta))
  6. y = np.ravel(r * np.cos(theta))
  7. z = f(x, y)
  8. ax = plt.axes(projection='3d')
  9. ax.scatter(x, y, z, c=z, cmap='viridis', linewidth=0.5)
  10. plt.show()

可以看到图形中还有许多地方需要修补,这些工作可以由ax.plot_trisurf函数完成。它首先找到一组所有点都连接起来的三角形,然后用这些三角形创建曲面。

 
  1. ax = plt.axes(projection='3d')
  2. ax.plot_trisurf(x, y, z,cmap='viridis', edgecolor='none');

虽然结果没有之前用均匀网格画的图完美,但是这种三角剖分方法很灵活,可以创建各种有趣的三维图。

莫比乌斯带

莫比乌斯带是把一根纸条扭转 180 度后,再把两头粘起来做成的纸带圈。从拓扑学的角度看,莫比乌斯带非常神奇,因为它总共只有一个面!

接下来让我们用matplotlib的三维功能来画一条莫比乌斯带。绘制的关键是想出它的绘图参数:由于它是一条二维带,因此需要两个内在维度。让我们把一维度定义为θ,取值范围为0~2 π;另一个维度是w,取值范围是-1~1,表示莫比乌斯带的宽度:

 
  1. theta = np.linspace(0, 2 * np.pi, 30)
  2. w = np.linspace(-0.25, 0.25, 8)
  3. w, theta = np.meshgrid(w, theta)

有了参数之后,我们必须确定带上每个点的直角坐标 ( xyz )。 仔细思考一下,我们可能会找到两种旋转关系:一种是圆圈绕着圆心旋转(角度用 θ 定义),另一种是莫比乌斯带在自己的坐标轴上旋转(角度用 Φ 定义)。因此,对于一条莫比乌斯带,我们必然会有环的一半扭转 180 度,即 Δ Φ = Δ θ / 2

phi = 0.5 * theta

现在用我们的三角学知识将极坐标转换成三维直角坐标。定义每个点到中心的距离(半径)r,那么直角坐标 (zyz ) 就是:

 
  1. r = 1 + w * np.cos(phi)
  2. x = np.ravel(r * np.cos(theta))
  3. y = np.ravel(r * np.sin(theta))
  4. z = np.ravel(w * np.sin(phi))

最后,要画出莫比乌斯带,还必须确保三角剖分是正确的。最好的实现方法就是首先用基本参数化方法定义三角剖分,然后用Matplotlib将这个三角剖分映射到莫比乌斯带的三维空间里,这样就可以画出图形:

 
  1. from matplotlib.tri import Triangulation
  2. tri = Triangulation(np.ravel(w), np.ravel(theta))
  3. ax = plt.axes(projection='3d')
  4. ax.plot_trisurf(x, y, z, triangles=tri.triangles,
  5. cmap='viridis', linewidths=0.2);
  6. ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1);

编程要求

本关的编程任务是补全右侧上部代码编辑区内的相应代码,根据输入数据x、y计算z坐标值,计算方式为np.sin(-x * y)。再绘制曲面图并设置颜色条为jet、线宽为0.2,具体可视化要求如下:

  • 图形的figsize(10, 10)

  • 文件名为Task2/img/T1.png

  • 具体要求请参见后续测试样例。

请先仔细阅读右侧上部代码编辑区内给出的代码框架,再开始你的编程工作! ####测试说明 平台会对你编写的代码进行测试,对比你输出的数值与实际正确的数值,只有所有数据全部计算正确才能进入下一关。

测试输入:

无测试输入

预期输出:你的答案与正确答案一致


开始你的任务吧,祝你成功!

import matplotlib 
matplotlib.use("Agg")
import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
 

def student(x,y):
    # ********* Begin *********#
    fig=plt.figure(figsize=(10,10))
    ax = plt.axes(projection='3d')
    z=np.sin(-x * y)
    ax.plot_trisurf(x, y, z,cmap='jet', edgecolor='none');
    plt.savefig('Task2/img/T1.png')
    plt.show()
    
    # ********* End *********#

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值