我不确定这在 Mathoverflow 上是否会更好,但我想我会先在这里检查。我尽量做到简洁明了;如果有什么需要清理的,请告诉我。
背景
我在 R3 中有两组点,它们以(或多或少)任意定向的椭圆体的形式分布。我希望在这两个椭圆体之间插入一个管状结构。我也有这个管状结构所需中心线的坐标。
我使用在 Matlab 中实现的 Khachiyan 算法 [1] 以最小体积包围椭圆体来近似任一端的椭圆体,该算法返回椭圆体中心的坐标 (C) 和中心形式的椭圆矩阵 (A),这样:
(x - C)' * A * (x - C) = 1
然后我使用奇异值分解提取椭圆体的轴长度 (a,b,c) 和旋转矩阵 (V):
[U,D,V] = svd(A);
a = 1/sqrt(D(1,1));
b = 1/sqrt(D(2,2));
c = 1/sqrt(D(3,3));
我可以轻松地插入轴长度参数(例如线性、样条)。为了在方向之间进行插值,我首先将旋转矩阵转换为四元数表示。然后对于沿中心线的每个点,我使用在另一个 Matlab 文件 [2] 中实现的球面线性插值 (SLERP):
for iPoint = 1 : nPoints
t = iPoint / (nPoints + 2);
quat = slerp(startQuat,endQuat,t,0.001);
R = quat2rot(quat);
end
这就是我卡住的地方。
不幸的是,尽管 SLERP “在其四元数端点之间给出了一条最直和最短的路径”,[3] 得到的插值椭球有时会在“错误”的方向上旋转。也就是说,插值不会产生光滑的管子,而是会产生一种扭曲的椭圆柱(见下图)。
我尝试检查两个四元数的点积是否为负,如果是,则使用quatinv
. 但是,反转会导致完全不正确的结果(请参见下面的第二张附图)。
我的问题是:为什么会发生这种情况,我能做些什么来纠正这种行为?也就是说,如何沿着两个椭球方向之间的“真实”最短路径进行插值?
任何建议将不胜感激!
更新
我已经创建了一个最小的工作示例和一个所需的数据文件。我还附上了结果的截图。我已经将它们压缩并上传到 Dropbox。[4]
[2] http://www.mathworks.com/matlabcentral/fileexchange/11827-slerp/content/slerp.m
[3] https://en.wikipedia.org/wiki/Slerp
[4] https://dl.dropboxusercontent.com/u/38218/ellipsoidInterpolation.zip