python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python粽子

基于Python绘制一个会动的3D立体粽子

作者:微小冷

下周就要到端午节了,所以本文小编就来和大家分享一个有趣的Python项目——绘制会动的3D立体粽子,文中的示例代码讲解详细,感兴趣的可以了解一下

粽子曲面

之前通过matplotlib绘制了圆锥曲面,但matplotlib绘制曲面图有几个问题,其中plot_surface需要有规范的xOy坐标,然后根据其坐标绘制z轴参数;plot_trisurf则必须有明确的三角面的顶点。这些限制提高了绘制三维曲面的技术要求,所以接下来用open3d来以点云的形式来绘制一些更复杂的曲面。

首先就是下面这个参数方程对应的曲面

下面是绘图代码

import numpy as np
import open3d as o3d

def getSin(N):
    u = np.linspace(0, np.pi*2, N)
    v = np.linspace(0, np.pi*2, N)
    u,v = np.meshgrid(u,v)
    x = np.cos(u).reshape(-1)
    y = np.cos(v).reshape(-1)
    z = np.cos(u+v).reshape(-1)
    return np.array([x,y,z]).T

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(getSin(500))
o3d.visualization.draw_geometries([pcd])

最后效果如下,非常像一个粽子

真·粽子曲面

上面的粽子图,其实是散点图,只不过点数太多,看上去就比较连续,接下来通过open3d,将这个粽子的散点图,转换为粽子曲面。由于曲面生成的本质是绘制三角面,而随着点数的增多,所需绘制时间也就越长,故而少选一些点

tri = o3d.geometry.TriangleMesh

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(getSin(20))
mesh = tri.create_from_point_cloud_alpha_shape(pcd, 2)
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh], mesh_show_back_face=True)

其中,o3d.geometry.TriangleMesh是一个类,之所以将其重新赋值,皆因后面调用的生成曲面的方法名字太长,这样可以缩减一下一行的长度。

compute_vertex_normals用于生成法线,如果没有这个,最后得到的曲面是看不出三维效果的。

最终得到的效果如下,像是个金属质感的粽子,还挺好看的

点击Ctrl+数字,可以更改曲面的配色,为了表现得更加细腻,下面用100×100的网格来生成粽子曲面,效果如下

正弦曲面

粽子曲面又叫余弦曲面,如果把cos换成sin,那么就得到了正弦曲面

其绘图代码如下

import numpy as np
import open3d as o3d

def getCos(N):
    u = np.linspace(0, np.pi*2, N)
    v = np.linspace(0, np.pi*2, N)
    u,v = np.meshgrid(u,v)
    x = np.sin(u).reshape(-1)
    y = np.sin(v).reshape(-1)
    z = np.sin(u+v).reshape(-1)
    return np.array([x,y,z]).T

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(getCos(500))
pcd.estimate_normals()
o3d.visualization.draw_geometries([pcd])

其中,estimate_normals用于估计点的法线,这样在绘图的时候会产生漂亮的光效,最终绘图结果如下,可见正弦曲面和余弦曲面的确有着类似互补的性质。

到此这篇关于基于Python绘制一个会动的3D立体粽子的文章就介绍到这了,更多相关Python粽子内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文