Main Content

slerp

구면 선형 보간

R2019b 이후

설명

예제

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

쿼터니언 a와 쿼터니언 cslerp를 호출하고 보간 계수를 0.5로 지정합니다.

interpolationCoefficient = 0.5;

b = slerp(a,c,interpolationCoefficient);

slerp의 출력값 bac의 평균 회전을 나타냅니다. 확인을 위해 b를 오일러 각(단위: 도)으로 변환합니다.

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

     0     0     0

보간 계수는 01(구간의 끝점 포함) 사이의 정규화된 값으로 지정됩니다. 보간 계수 0a 쿼터니언에 대응하고, 보간 계수 1c 쿼터니언에 대응합니다. 계수 01slerp를 호출하여 확인합니다.

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 알고리즘은 두 쿼터니언을 연결하는 대권(great circle) 경로를 따라 보간합니다. 이 예제는 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과 세 쿼터니언 회전 간에 보간합니다. 경로가 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 객체로 구성된 배열로 지정됩니다.

q1, q2, T의 크기는 서로 호환되어야 합니다. 가장 간단한 경우는 셋이 동일한 크기이거나 셋 중 하나가 스칼라일 때입니다. 모든 차원에서 입력값의 차원 크기가 동일하거나 차원 중 하나가 1인 경우 두 입력값의 크기는 호환됩니다.

보간할 쿼터니언으로, 스칼라, 벡터, 행렬 또는 쿼터니언으로 구성된 다차원 배열로 지정됩니다.

q1, q2, T의 크기는 서로 호환되어야 합니다. 가장 간단한 경우는 셋이 동일한 크기이거나 셋 중 하나가 스칼라일 때입니다. 모든 차원에서 입력값의 차원 크기가 동일하거나 차원 크기 중 하나가 1인 경우 두 입력값의 크기는 호환됩니다.

보간 계수로, 스칼라, 벡터, 행렬 또는 각 요소가 [0, 1] 범위에 있는 숫자로 구성된 다차원 배열로 지정됩니다.

q1, q2, T의 크기는 서로 호환되어야 합니다. 가장 간단한 경우는 셋이 동일한 크기이거나 셋 중 하나가 스칼라일 때입니다. 모든 차원에서 입력값의 차원 크기가 동일하거나 차원 크기 중 하나가 1인 경우 두 입력값의 크기는 호환됩니다.

데이터형: single | double

출력 인수

모두 축소

보간된 쿼터니언으로, quaternion 객체 또는 quaternion 객체로 구성된 배열로 반환됩니다.

알고리즘

쿼터니언 구면 선형 보간(spherical linear interpolation, SLERP)은 평면에서의 선형 보간을 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++ 코드를 생성할 수 있습니다.

버전 내역

R2019b에 개발됨