我有一些由XYZ直角坐标点组成的三维任意曲线。这些点不是均匀分布的(存在时间因素)。如何使用给定数量的点“重建”曲线?我看到在3D建模程序中可以实现,所以我相信这是可能的,只是我不知道如何做。
根据回答,我需要用Python,所以我开始尝试将interparc转换为Python。 我已经完成了线性插值。 它可能效率低下且冗余,但也许对某些人有用。http://pastebin.com/L9NFvJyA
根据回答,我需要用Python,所以我开始尝试将interparc转换为Python。 我已经完成了线性插值。 它可能效率低下且冗余,但也许对某些人有用。http://pastebin.com/L9NFvJyA
t = linspace(0,1,500).^3;
x = sin(2*pi*t);
y = sin(pi*t);
z = cos(3*x + y);
plot3(x,y,z,'o')
grid on
box on
view(-9,12)
xyzi = interparc(100,x,y,z,'lin');
plot3(xyzi(:,1),xyzi(:,2),xyzi(:,3),'o')
box on
grid on
view(-9,12)
首先,感谢John D'Errico先生为interparc所做的贡献。他真是干得好!
我也曾面临这个问题,但不熟悉MATLAB引擎API。因此,我尝试将interparc Matlab代码的一部分转换为Python(仅包括线性插值器,因为它足以解决我的问题)。
下面是我的代码,希望能帮助所有寻求类似解决方案的Python开发人员:
import numpy as np
def interpcurve(N,pX,pY):
#equally spaced in arclength
N=np.transpose(np.linspace(0,1,N))
#how many points will be uniformly interpolated?
nt=N.size
#number of points on the curve
n=pX.size
pxy=np.array((pX,pY)).T
p1=pxy[0,:]
pend=pxy[-1,:]
last_segment= np.linalg.norm(np.subtract(p1,pend))
epsilon= 10*np.finfo(float).eps
#IF the two end points are not close enough lets close the curve
if last_segment > epsilon*np.linalg.norm(np.amax(abs(pxy),axis=0)):
pxy=np.vstack((pxy,p1))
nt = nt + 1
else:
print('Contour already closed')
pt=np.zeros((nt,2))
#Compute the chordal arclength of each segment.
chordlen = (np.sum(np.diff(pxy,axis=0)**2,axis=1))**(1/2)
#Normalize the arclengths to a unit total
chordlen = chordlen/np.sum(chordlen)
#cumulative arclength
cumarc = np.append(0,np.cumsum(chordlen))
tbins= np.digitize(N,cumarc) # bin index in which each N is in
#catch any problems at the ends
tbins[np.where(tbins<=0 | (N<=0))]=1
tbins[np.where(tbins >= n | (N >= 1))] = n - 1
s = np.divide((N - cumarc[tbins]),chordlen[tbins-1])
pt = pxy[tbins,:] + np.multiply((pxy[tbins,:] - pxy[tbins-1,:]),(np.vstack([s]*2)).T)
return pt
d = totalCurveLength / (numberOfPoints - 1)
,并将曲线分成(numberOfPoints - 1)
长度为d
的块。interparc
假设您的点按路径顺序列出(即点从起点到终点沿曲线追踪)。如果使用真实世界的数据,情况可能不是这样的。libigl
按路径顺序对点进行排序:import igl
path, _, _ = igl.edges_to_path(edges) # edges = N x 2 array of point indices
points = points[path]
# Now use `interparc`...
pykdtree
:
edges
的空的N X 2
数组points
数据集中随机选择一个点(比如points
的索引5
)KDTree
找到数据中距离最近的两个邻居的索引edges
中
(例如,如果points[5]
与points[10]
和points[3]
相连,你可以这样做:edges = np.append(edges, [[5, 10], [5, 3]], axis=0)
points
中弹出5
、10
和3
的点,并继续在点10
和3
处执行算法,直到没有剩余的点为止。不太确定我是否理解了,但是可以尝试存储点与点之间的增量而不是实际数据,然后从增量重建曲线,这样就不会有空白区域了。但是这将改变曲线的形状。