使用网格库在表面上两点之间的测地线路径

问题描述 投票:0回答:1

我想使用 Python 获取 3D 表面上两点之间的最短(测地线)路径的路径坐标。该解决方案已经以某种方式显示在这篇文章中接受的答案中,但是,我无法重现 Fedor 的结果,因为我不理解 meshlib 期望提供点位置的格式。

测地线路径计算是使用computeGeodesicPath函数完成的,该函数需要MeshTriPoints作为输入。不幸的是,我不明白这种格式是如何工作的以及如何从笛卡尔点坐标转换为它。这是一个简单的圆柱形 3D 表面的示例,但我希望它也能够在更复杂的表面上工作。

import numpy as np
import meshlib.mrmeshnumpy as mnp

def cyl2cart(rho,phi,z):
    return rho*np.cos(phi),rho*np.sin(phi),z

# cylinder coordinates
N = 101
radius = 5

rho = radius*np.ones(N)
phi = np.linspace(0,2*np.pi,37) # 10 degree steps
z = np.linspace(-10,10,N)

# surface grid coordinates
x = np.outer(rho,np.cos(phi))
y = np.outer(rho,np.sin(phi))
z = np.outer(z,np.ones(len(phi)))

# create mesh
mesh = mnp.meshFromUVPoints(x, y, z)

# define two points on the surface
# point1
rhop = radius
phip = -10/180.*np.pi
zp = -3
xp1,yp1,zp1 = cyl2cart(rhop, phip, zp)
# point2
rhop = radius
phip = 60/180.*np.pi
zp = 8
xp2,yp2,zp2 = cyl2cart(rhop, phip, zp)

# This part is not working because I don't understand how to provide the point coordinates
# p1 = mpy.MeshTriPoint(??)
# p2 = mpy.MeshTriPoint(??)
# mpy.computeGeodesicPath(mesh, p1, p2)

#%% optional plot with plotly
import plotly.graph_objects as go
# extract numpy arrays
verts = mnp.getNumpyVerts(mesh)
faces = mnp.getNumpyFaces(mesh.topology)
# prepare data for plotly
vertsT = np.transpose(verts)
facesT = np.transpose(faces)
# draw
fig = go.Figure(data=[
    go.Mesh3d(
        x = vertsT[0],
        y = vertsT[1],
        z = vertsT[2],
        i = facesT[0],
        j = facesT[1],
        k = facesT[2]
    )
])
fig.add_trace(go.Scatter3d(x=[xp1,xp2],y=[yp1,yp2],z=[zp1,zp2],mode='markers',marker={'size':8,'symbol':'circle'}))

fig.update_layout(scene=dict(aspectmode='data'))
fig.show(renderer='browser')
python path 3d surface
1个回答
0
投票

mpy.MeshTriPoint
是附加到网格对象的点。要从笛卡尔点获得
mpy.MeshTriPoint
,将世界点投影到网格并找到相应的MeshTriPoint:

from meshlib import mrmeshpy as mm

mesh = mm.makeSphere( mm.SphereParams() ) # simple mesh for example

startPoint = mm.Vector3f(-1,-1,-1) # cartesian start coordinate
stopPoint = mm.Vector3f(1,1,1) # cartesian stop coordinate

# find corresponding MeshTriPoints
startMtp = mm.findProjection( startPoint, mesh).mtp
stopMtp = mm.findProjection( stopPoint, mesh).mtp

path = mm.computeGeodesicPath(mesh,startMtp,stopMtp,mm.GeodesicPathApprox.DijkstraBiDir)

# print path
for p in path:
     pc = mesh.edgePoint(p)
     print(pc.x,pc.y,pc.z)
© www.soinside.com 2019 - 2024. All rights reserved.