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)")

Figure contains an axes object. The axes object with xlabel Interpolation Coefficient, ylabel Z-Axis Rotation (Degrees) contains 3 objects of type line. One or more of the lines displays its values using only markers These objects represent Path to 179 degrees, Path to 180 degrees, Path to 181 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

Figure contains an axes object. The axes object contains 2 objects of type surface, scatter.

内挿された四元数は 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 つの四元数 q1 と q2 を与えると、SLERP は q1 と q2 を連結する大圏に沿って新しい四元数 q0 を内挿します。内挿係数 T により、出力の四元数が q1 と q2 のいずれかにどの程度近くなるかが決まります。

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

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

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

参照

[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 で導入