球坐标中的插值曲线

时间:2018-01-18 23:06:56

标签: matlab 3d interpolation curve-fitting

我有点,属于3D空间中的一些非参数曲线。 我需要在球坐标中工作,并在给定的azimuthelevation值中插入给定的曲线。

你能帮我解决这种插值的算法吗?

P.S。我不确定,根据我的问题,在1D空间中绘制的 1D曲线是明确的。所以,以防下面的代码创建这样的,但是参数化。

x=linspace(-2*pi,2*pi,10^3);
y=sin(x);
z=sinh(x);

更新:

感谢@jodag关于上采样的非常好的帖子。 slerp很完美!然而,我的问题是不同的,或者我不明白如何使用上采样来解决它。 假设我将我的点定义为数组(只是演示的一些虚拟数据):

x_given = rand(9, 1) - 0.5; 
y_given = rand(9, 1) - 0.5; 
z_given = rand(9, 1) - 0.5; 
x_given(end+1) = x_given(1); % should work for closed curves
y_given(end+1) = y_given(1); % should work for closed curves
z_given(end+1) = x_given(1); % should work for closed curves

我想查找给定x_i, y_i, z_ielevation_q的所有积分(azimuth_q):

elevation_q = pi./4;
azimuth_q = pi./7;
[x_i, y_i ,z_i] = interpolateCurve(x_given, y_given, y_given, elevation_q, azimuth_q);

那就是我真正需要的。我明白,我们不需要前后从笛卡尔坐标到球面坐标。但即使我将x_given, y_given, y_given替换为elevation_given, azimuth_given, r_given,我也不知道如何编写interpolateCurve()函数。

1 个答案:

答案 0 :(得分:6)

这是高维空间中曲线的线性插值的示例。请注意,我引入了与点的索引相对应的参数化变量class Foo[T](t: T)(implicit int: Numeric[T]) { import int._ val sum = t + t }

t

问题不清楚这是否是您实际需要的内容。在球坐标中存在直接插值的问题。例如,如果两个点彼此接近但一个方位角= -179度而另一个方位角= 179而不是采用最短的2度路径,则插值将产生跨越[-179,179]的样本。您可能感兴趣的是slerp,它可以提供更好的插值结果。

我编写了以下slerp示例来演示。请注意,slerp要求定义function [xq,yq,zq] = interp_sph(x,y,z,upsample) [az,el,r] = cart2sph(x,y,z); t = 1:numel(x); tq = 1:(1/upsample):numel(x); azq = interp1(t,az,tq); elq = interp1(t,el,tq); rq = interp1(t,r,tq); [xq,yq,zq] = sph2cart(azq,elq,rq); end ,其中1/sin(theta)是函数中两点之间的角度。如果theta那么我们就会遇到问题并且slerp不会工作,所以如果您的数据接近原点,请小心。

theta == pi

要使用function [xq,yq,zq] = interp_slerp(x,y,z,upsample) r = sqrt(x.^2+y.^2+z.^2); vq = zeros(3,(upsample-1)*(numel(x)-1)+1); for idx = 1:numel(x)-1 t = 0:1; tq = linspace(0,1,upsample); % compute interpolated direction dq = slerp([x(idx),y(idx),z(idx)],[x(idx+1),y(idx+1),z(idx+1)],tq); % linearly interpolate radius rq = interp1(t,r(idx:(idx+1)),tq); % get interpolated path idxq = (idx-1)*upsample + 1; vq(:,idxq:(idxq+(upsample-1))) = bsxfun(@times,rq,dq); end xq = vq(1,:); yq = vq(2,:); zq = vq(3,:); end function pq = slerp(p0,p1,t) p0 = p0(:) / norm(p0); p1 = p1(:) / norm(p1); theta = acos( dot(p0,p1) ); if(0==theta) pq = a; elseif(pi==theta) error('Angle between points cannot be exactly pi.'); else pq = bsxfun(@times,(sin((1.0-t)*theta)/sin(theta)),p0) + bsxfun(@times,(sin(t*theta)/sin(theta)),p1); end end 演示问题,请考虑以下示例。

interp_sph

这将产生下图。请注意,当方位角从正到负时,球形插值需要很长时间,但是slerp会采用预期的路径。

enter image description here