我不确定在Mathoverflow上是否会更好地问这个问题,但我想我会先在这里查看。我试图尽可能简洁明了;如果有任何需要清理的地方请告诉我。
背景
我在R3中有两组点,以(或多或少)任意定向的椭圆体的形式分布。我希望在这两个椭圆体之间插入一个管状结构。我还有这个管状结构所需中心线的坐标。
我使用在Matlab中实现的Khachiyan算法[1]近似椭圆体的最小体积,使用Khachiyan算法,它返回椭圆体(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
答案 0 :(得分:0)
解决方案是通过一个参考椭圆体的旋转矩阵的倒数来旋转所有物体,使得该参考椭球体是轴对齐的(即没有旋转)。然后在插入每个椭球后,通过乘以原始旋转矩阵将其旋转回原始参考帧。
我附上了结果截图:
<强>更新强>
显然这在每种情况下都不起作用。我发布了一个新问题here。