如何在曲线上均匀地重新分布点

use*_*637 3 python math 3d

我有一些由XYZ笛卡尔点列表组成的三维任意曲线.点数不均匀分布(时间因素).如何使用构成曲线的给定数量的点"重建"曲线.我看到这在3D建模程序中完成,所以我很确定它可能,我只是不知道如何.

在此输入图像描述

基于答案,我在python中需要它,所以我开始努力将interparc转换为python.我得到了线性插值.它可能效率低下并且有冗余,但也许对某人有用http://pastebin.com/L9NFvJyA

小智 8

我会使用interparc,我的工具就是为了做到这一点.它通过2维或更多维的一般空间曲线拟合样条曲线,然后选择沿该曲线的距离相等的点.在三次样条函数的情况下,解决方案使用一个odesolver来做必须是数值积分的事情,因此它有点慢,但它仍然相当快.在许多情况下,简单的线性插值(我在这里使用)将是完全足够的,并且非常快.

曲线可以是完全一般的,甚至是自身交叉.我将给出一个三维空间曲线的简单示例:

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

xyzi = interparc(100,x,y,z,'lin');
plot3(xyzi(:,1),xyzi(:,2),xyzi(:,3),'o')
box on
grid on
view(-9,12)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 你有写下算法吗?我不使用 matlab 并且很难解析正在发生的事情 (2认同)

Fra*_*nha 7

首先,感谢 John D'Errico 先生的 interparc。多棒的工作!

我也面临这个问题,但不熟悉 MATLAB 引擎 API。鉴于此,我尝试将部分 interparc Matlab 代码转换为 Python(仅包括线性插值,因为它足以解决我的问题)。

所以这是我的代码;希望它可以帮助所有寻求类似内容的pythonics:

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 
Run Code Online (Sandbox Code Playgroud)

  • 除了之前的评论之外,在摆脱曲线闭合块后,我还必须更改以下行: s = np.divide((N - cumarc[tbins-1]),chordlen[tbins-1]) pt = pxy [tbins-1,:] + np.multiply((pxy[tbins,:] - pxy[tbins-1,:]),(np.vstack([s]*ndim)).T)。现在,这给出了与原始 Matlab 线性插值函数相同的结果。 (2认同)