文章目录
- 粽子曲面
- 真·粽子曲面
- 正弦曲面
粽子曲面
之前通过matplotlib绘制了圆锥曲面,但matplotlib绘制曲面图有几个问题,其中plot_surface需要有规范的xOy坐标,然后根据其坐标绘制z轴参数;plot_trisurf则必须有明确的三角面的顶点。这些限制提高了绘制三维曲面的技术要求,所以接下来用open3d来以点云的形式来绘制一些更复杂的曲面。
首先就是下面这个参数方程对应的曲面
{ x = a cos u y = a cos v z = a cos ( u + v ) u , v ∈ ( 0 , 2 π ) \left\{\begin{aligned} x&=a\cos u\\ y&=a\cos v\\ z&=a\cos(u+v) \end{aligned}\right.\quad u,v \in (0,2\pi) ⎩ ⎨ ⎧xyz=acosu=acosv=acos(u+v)u,v∈(0,2π)
下面是绘图代码
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
100\times100
100×100的网格来生成粽子曲面,效果如下
正弦曲面
粽子曲面又叫余弦曲面,如果把 cos \cos cos换成 sin \sin sin,那么就得到了正弦曲面
{ x = a sin u y = a sin v z = a sin ( u + v ) u , v ∈ ( 0 , 2 π ) \left\{\begin{aligned} x&=a\sin u\\ y&=a\sin v\\ z&=a\sin(u+v) \end{aligned}\right.\quad u,v \in (0,2\pi) ⎩ ⎨ ⎧xyz=asinu=asinv=asin(u+v)u,v∈(0,2π)
其绘图代码如下
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用于估计点的法线,这样在绘图的时候会产生漂亮的光效,最终绘图结果如下,可见正弦曲面和余弦曲面的确有着类似互补的性质。