Matlab 球坐标系下的插值曲线

Matlab 球坐标系下的插值曲线,matlab,3d,interpolation,curve-fitting,Matlab,3d,Interpolation,Curve Fitting,我有点,它属于三维空间中的一些非参数曲线。 我需要在球坐标系下工作,在给定的方位角和仰角值内插给定的曲线 你能帮我弄一下这种插值的算法吗 另外,我不确定,从我的问题来看,在一维空间中绘制一维曲线的想法是否清晰。所以,以防万一下面的代码创建了这样的,但参数化的 x=linspace(-2*pi,2*pi,10^3); y=sin(x); z=sinh(x); 更新: 感谢@jodag关于上采样的非常好的帖子。slerp是完美的!然而,我的问题是不同的,或者我不知道如何使用上采样来解决它。 假设我

我有点,它属于三维空间中的一些非参数曲线。 我需要在球坐标系下工作,在给定的方位角和仰角值内插给定的曲线

你能帮我弄一下这种插值的算法吗

另外,我不确定,从我的问题来看,在一维空间中绘制一维曲线的想法是否清晰。所以,以防万一下面的代码创建了这样的,但参数化的

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_I:


这就是我真正需要的。我明白,我们不需要从笛卡尔坐标系跳到球坐标系。但即使我将x_给定,y_给定,y_给定替换为仰角给定,方位角给定,r_给定,我也不知道如何编写插值曲线函数。

这是一个高维空间中曲线线性插值的示例。注意,我引入了一个参数化变量t,它对应于点的索引

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
这个问题不清楚你是否真的在寻找这个。球坐标系中的直接插值肯定存在问题。例如,如果两个点彼此相邻,但一个点的方位角=-179度,另一个点的方位角=179度,则插值将生成跨越[-179179]的采样,而不是采用最短的2度路径。您可能感兴趣的是,哪一种插值结果更好

我编写了下面的slerp示例来演示。请注意,slerp要求定义1/sintheta,其中θ是函数中两点之间的角度。如果θ=π,那么我们就有问题了,slerp将不起作用,所以如果您的数据接近原点,请小心

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

用IpPSPH演示问题,考虑下面的例子。

% create test path
az = pi+sin(linspace(pi/2,3*pi/2,10));
el = cos(linspace(-pi,pi,10));
r = 1 + 1/5*sin(6*az).*sin(5*el);
[x,y,z] = sph2cart(az,el,r);

% test both spherical interpolation and slerp
upsample = 20;
[xq_sph,yq_sph,zq_sph] = interp_sph(x,y,z,upsample);
[xq_slerp,yq_slerp,zq_slerp] = interp_slerp(x,y,z,upsample);

% plot results
plot3(x,y,z,'LineWidth',2); hold on;
plot3(xq_sph,yq_sph,zq_sph,'LineWidth',2);
plot3(xq_slerp,yq_slerp,zq_slerp,'LineWidth',2);
axis('vis3d');
axis([-1,1,-1,1,-1,1]);
grid('on');
legend('Cartisian', 'Spherical', 'SLERP');
这将生成下面的图。请注意,当方位角从正变为负时,球面插值会占用很长的时间,但slerp会采用预期的路线


这是一个高维空间中曲线的线性插值示例。注意,我引入了一个参数化变量t,它对应于点的索引

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
这个问题不清楚你是否真的在寻找这个。球坐标系中的直接插值肯定存在问题。例如,如果两个点彼此相邻,但一个点的方位角=-179度,另一个点的方位角=179度,则插值将生成跨越[-179179]的采样,而不是采用最短的2度路径。您可能感兴趣的是,哪一种插值结果更好

我编写了下面的slerp示例来演示。请注意,slerp要求定义1/sintheta,其中θ是函数中两点之间的角度。如果θ=π,那么我们就有问题了,slerp将不起作用,所以如果您的数据接近原点,请小心

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

用IpPSPH演示问题,考虑下面的例子。

% create test path
az = pi+sin(linspace(pi/2,3*pi/2,10));
el = cos(linspace(-pi,pi,10));
r = 1 + 1/5*sin(6*az).*sin(5*el);
[x,y,z] = sph2cart(az,el,r);

% test both spherical interpolation and slerp
upsample = 20;
[xq_sph,yq_sph,zq_sph] = interp_sph(x,y,z,upsample);
[xq_slerp,yq_slerp,zq_slerp] = interp_slerp(x,y,z,upsample);

% plot results
plot3(x,y,z,'LineWidth',2); hold on;
plot3(xq_sph,yq_sph,zq_sph,'LineWidth',2);
plot3(xq_slerp,yq_slerp,zq_slerp,'LineWidth',2);
axis('vis3d');
axis([-1,1,-1,1,-1,1]);
grid('on');
legend('Cartisian', 'Spherical', 'SLERP');
这将生成下面的图。请注意,当方位角从正变为负时,球面插值会占用很长的时间,但slerp会采用预期的路线


在球面中,它仍然是3d的。问题是我因为3d而陷入困境。因为它是曲线而不是函数。例如,它可能是变形的圆。您想自己编写插值器吗?如果您使用的是matlab,请尝试帮助interp3。@zlon我想我理解您的提问,但我相信这个问题是不合适的。您的示例对应于三维空间中的曲线,您希望给出第一个和第二个坐标,并确定第三个坐标是正确的吗?如果你的信号是一个曲面,那么很好,我们只需拟合一个曲面,然后查询它。然而,由于我们要处理一条曲线,我们首先必须确定曲线上的任何点是否具有给定的2个坐标。我还没有想出一个不依赖大量启发法的解决方法。@jodag你完全正确。这就是问题所在。如果它比我们假设的更简单,它总是以0,0,0在中间循环,那么我可以旋转它,以得到任何给定高程的点。我还认为,我可能会重新表述这个问题,如何插值三维曲线和直线的交点,这会有帮助吗?我开始认为这可能是一个球面,它仍然是三维的。问题是我因为3d而陷入困境。因为它是曲线而不是函数。例如,它可能是变形的圆。您想自己编写插值器吗?如果您使用的是matlab,请尝试帮助interp3。@zlon我想我理解您的提问,但我相信这个问题是不合适的。您的示例对应于三维空间中的曲线,您希望给出第一个和第二个
协调并确定第三个坐标是对的?如果你的信号是一个曲面,那么很好,我们只需拟合一个曲面,然后查询它。然而,由于我们要处理一条曲线,我们首先必须确定曲线上的任何点是否具有给定的2个坐标。我还没有想出一个不依赖大量启发法的解决方法。@jodag你完全正确。这就是问题所在。如果它比我们假设的更简单,它总是以0,0,0在中间循环,那么我可以旋转它,以得到任何给定高程的点。我还认为,我可以重新表述这个问题,如何插值三维曲线和直线的交点,这会有帮助吗?我开始认为这可能是一个感谢你们的完美答案。slerp太棒了,我从来没听说过。然而,我需要插值,但不需要上采样。我已经更新了我的问题。你能看一下吗?谢谢你的完美回答。slerp太棒了,我从来没听说过。然而,我需要插值,但不需要上采样。我已经更新了我的问题。你能帮我看看吗?