如何解决Python - 在 3D 样条上找到最接近 3D 点的点
我有 2 个带有 3D 点的数组(名称、X、Y、Z)。第一个数组包含参考点,我通过它绘制样条。第二个数组包含测量点,从中我需要计算样条的法线并获得样条上法线的坐标(我需要计算测量点的 XY 和高度标准偏差)。这是测试数据(其实我有几千分):
r1,1.5602,6.0310,4.8289
r2,1.6453,5.8504,4.8428
r3,1.7172,5.6732,4.8428
r4,1.8018,5.5296,4.8474
r5,1.8700,5.3597,4.8414
第二个数组 - 测量点:
m1,1.8592,5.4707,4.8212
m2,1.7642,5.6362,4.8441
m3,1.6842,5.7920,4.8424
m4,1.6048,5.9707,4.8465
我写的代码,读取数据,计算样条(使用scipy)并通过matplotlib显示:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
# import measured points
filename = "measpts.csv"
meas_pts = np.genfromtxt(filename,delimiter=',')
# import reference points
filename = "refpts.csv"
ref = np.genfromtxt(filename,')
# divide data to X,Y,Z
x = ref[:,2]
y = ref[:,1]
z = ref[:,3]
# spline interpolation
tck,u = interpolate.splprep([x,y,z],s=0)
u_new = np.linspace(u.min(),u.max(),1000000)
x_new,y_new,z_new = interpolate.splev(u_new,tck,der=0)
xs = tck[1][0]
ys = tck[1][1]
zs = tck[1][2]
# PLOT 3D
fig = plt.figure()
ax3d = fig.add_subplot(111,projection='3d',proj_type='ortho')
ax3d.plot(x,z,'ro') # ref points
ax3d.plot(xs,ys,zs,'yo') # spline knots
ax3d.plot(x_new,z_new,'b--') # spline
ax3d.plot(meas_pts[:,2],meas_pts[:,1],3],'g*') # measured points
# ax3d.view_init(90,-90) # 2D TOP view
# ax3d.view_init(0,-90) # 2D from SOUTH to norTH view
# ax3d.view_init(0,0) # 2D from EAST to WEST view
plt.show()
总结:我需要数组包含对:[[测量点X,Y,Z],[样条X,Y,Z上最近(法线)点]]
解决方法
给定 3d 空间中的一个点 P 和一条线,点 P 到线的点的距离是盒子的对角线,所以你希望最小化这条对角线,最小距离将垂直于线
您可以使用此属性。所以,例如
tablefunc()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# generate sample line
x = np.linspace(-2,2,100)
y = np.cbrt( np.exp(2*x) -1 )
z = (y + 1) * (y - 2)
# a point
P = (-1,3,2)
# 3d plot
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d',proj_type='ortho')
ax.plot(x,y,z)
ax.plot(P[0],P[1],P[2],'or')
plt.show()
给予
def distance_3d(x,z,x0,y0,z0):
"""
3d distance from a point and a line
"""
dx = x - x0
dy = y - y0
dz = z - z0
d = np.sqrt(dx**2 + dy**2 + dz**2)
return d
def min_distance(x,P,precision=5):
"""
Compute minimum/a distance/s between
a point P[x0,z0] and a curve (x,z)
rounded at `precision`.
ARGS:
x,z (array)
P (3dtuple)
precision (integer)
Returns min indexes and distances array.
"""
# compute distance
d = distance_3d(x,P[0],P[2])
d = np.round(d,precision)
# find the minima
glob_min_idxs = np.argwhere(d==np.min(d)).ravel()
return glob_min_idxs,d
min_idx,d = min_distance(x,P)
fig = plt.figure()
ax = fig.add_subplot(111,'or')
ax.plot(x[min_idx],y[min_idx],z[min_idx],'ok')
for idx in min_idx:
ax.plot(
[P[0],x[idx]],[P[1],y[idx]],[P[2],z[idx]],'k--'
)
plt.show()
您可以根据需要实现类似的功能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。