Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

slerp

球面線形内挿

R2020a 以降

説明

q0 = slerp(q1,q2,T) は、q1q2 の間を球面に沿って内挿係数 T で内挿します。この関数では、常に q1q2 の間のより短い内挿パスが選択されます。

すべて折りたたむ

2 つの四元数を作成します。解釈は次のとおりです。

  1. a = "z" 軸を中心とする 45 度の回転

  2. c = "z" 軸を中心とする -45 度の回転

a = quaternion([45,0,0],"eulerd","ZYX","frame");
c = quaternion([-45,0,0],"eulerd","ZYX","frame");

四元数 ac を指定して slerp を呼び出し、内挿係数を 0.5 と指定します。

interpolationCoefficient = 0.5;

b = slerp(a,c,interpolationCoefficient);

slerp の出力 b は、ac の平均回転を表します。検証するには、b を度単位のオイラー角に変換します。

averageRotation = eulerd(b,"ZYX","frame")
averageRotation = 1×3

     0     0     0

内挿係数は 0 以上 1 以下の正規化された値として指定します。内挿係数 0a の四元数に対応し、内挿係数 1c の四元数に対応します。確認するには、係数 01 を指定して slerp を呼び出します。

b = slerp(a,c,[0,1]);
eulerd(b,"ZYX","frame")
ans = 2×3

   45.0000         0         0
  -45.0000         0         0

等間隔の内挿係数の配列を指定することで、四元数間の滑らかなパスを作成できます。

path = 0:0.1:1;

interpolatedQuaternions = slerp(a,c,path);

単一の軸のみの回転を表す四元数の場合、等間隔の内挿係数を指定すると、結果の四元数でオイラー角が等間隔になります。interpolatedQuaternions をオイラー角に変換し、パス内の角度の差が一定であることを確認します。

k = eulerd(interpolatedQuaternions,"ZYX","frame");
abc = abs(diff(k))
abc = 10×3

    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0
    9.0000         0         0

あるいは、関数 dist を使用して、内挿された四元数間の距離が一定であることを確認できます。関数 dist は角距離をラジアン単位で返します。比較しやすいように度単位に変換します。

def = rad2deg(dist(interpolatedQuaternions(2:end),interpolatedQuaternions(1:end-1)))
def = 1×10

    9.0000    9.0000    9.0000    9.0000    9.0000    9.0000    9.0000    9.0000    9.0000    9.0000

SLERP アルゴリズムでは、2 つの四元数を連結する大圏パスに沿って内挿を行います。この例では、SLERP アルゴリズムで大圏パスがどのように最小化されるかを示します。

4 つの四元数を定義します。

  1. q0 - グローバル座標系から回転していないことを示す四元数

  2. q179 - "z" 軸を中心とする 179 度の回転を示す四元数

  3. q180 - "z" 軸を中心とする 180 度の回転を示す四元数

  4. q181 - "z" 軸を中心とする 181 度の回転を示す四元数

q0 = ones(1,"quaternion");
q179 = quaternion([179,0,0],"eulerd","ZYX","frame");
q180 = quaternion([180,0,0],"eulerd","ZYX","frame");
q181 = quaternion([181,0,0],"eulerd","ZYX","frame");

slerp を使用して、q0 と 3 つの四元数回転の間を内挿します。10 ステップでパスを通過するように指定します。

T = linspace(0,1,10);

q179path = slerp(q0,q179,T);
q180path = slerp(q0,q180,T);
q181path = slerp(q0,q181,T);

各パスを度単位のオイラー角でプロットします。

q179pathEuler = eulerd(q179path,"ZYX","frame");
q180pathEuler = eulerd(q180path,"ZYX","frame");
q181pathEuler = eulerd(q181path,"ZYX","frame");

plot(T,q179pathEuler(:,1),"bo", ...
     T,q180pathEuler(:,1),"r*", ...
     T,q181pathEuler(:,1),"gd");
legend("Path to 179 degrees", ...
       "Path to 180 degrees", ...
       "Path to 181 degrees")
xlabel("Interpolation Coefficient")
ylabel("Z-Axis Rotation (Degrees)")

q0q179 の間のパスは、時計回りで大圏距離を最小化します。q0q181 の間のパスは、反時計回りで大圏距離を最小化します。q0q180 の間のパスは、数値の丸めに応じて時計回りか反時計回りのいずれかになります。

2 つの四元数を作成します。

q1 = quaternion([75,-20,-10],"eulerd","ZYX","frame");
q2 = quaternion([-45,20,30],"eulerd","ZYX","frame");

内挿係数を定義します。

T = 0:0.01:1;

内挿された四元数を取得します。

quats = slerp(q1,q2,T);

対応する回転の点を取得します。

pts = rotatepoint(quats,[1 0 0]);

内挿された四元数を単位球面上に表示します。

figure
[X,Y,Z] = sphere;
surf(X,Y,Z,FaceColor=[0.57 0.57 0.57])
hold on

scatter3(pts(:,1),pts(:,2),pts(:,3))
view([69.23 36.60])
axis equal

内挿された四元数は q1 から q2 までのより短いパスをたどることに注意してください。

入力引数

すべて折りたたむ

内挿する四元数。quaternion オブジェクト、任意の次元の quaternion オブジェクトの配列として指定します。

q1q2、および T のサイズは互換性がなければなりません。最も簡単なケースでは、それらを同じサイズにするか、いずれかをスカラーにすることができます。すべての次元について、入力の次元サイズが同じであるか、いずれかが 1 であれば、2 つの入力のサイズには互換性があります。

内挿する四元数。quaternion のスカラー、ベクトル、行列または多次元配列として指定します。

q1q2、および T のサイズは互換性がなければなりません。最も簡単なケースでは、それらを同じサイズにするか、いずれかをスカラーにすることができます。すべての次元について、入力の次元サイズが同じであるか、いずれかの次元サイズが 1 であれば、2 つの入力のサイズには互換性があります。

内挿係数。各要素が範囲 [0, 1] の数値であるスカラー、ベクトル、行列、または多次元配列として指定します。

q1q2、および T のサイズは互換性がなければなりません。最も簡単なケースでは、それらを同じサイズにするか、いずれかをスカラーにすることができます。すべての次元について、入力の次元サイズが同じであるか、いずれかの次元サイズが 1 であれば、2 つの入力のサイズには互換性があります。

データ型: single | double

出力引数

すべて折りたたむ

内挿された四元数。quaternion オブジェクト、または quaternion オブジェクトの配列として返されます。

アルゴリズム

四元数の球面線形内挿 (SLERP、spherical linear interpolation の略) は、平面に沿った線形内挿を 3 次元の球面内挿に拡張したものです。このアルゴリズムは、[1]で初めて提案されました。2 つの四元数 q1q2 を与えると、SLERP は q1q2 を連結する大圏に沿って新しい四元数 q0 を内挿します。内挿係数 T により、出力の四元数が q1q2 のいずれかにどの程度近くなるかが決まります。

SLERP アルゴリズムは正弦波で記述できます。

q0=sin((1T)θ)sin(θ)q1+sin(Tθ)sin(θ)q2

ここで、q1q2 は正規化された四元数、θq1q2 の間の角距離の半分です。

参照

[1] Shoemake, Ken. "Animating Rotation with Quaternion Curves." ACM SIGGRAPH Computer Graphics Vol. 19, Issue 3, 1985, pp. 245–254.

拡張機能

C/C++ コード生成
MATLAB® Coder™ を使用して C および C++ コードを生成します。

バージョン履歴

R2020a で導入