有兩個向量,我們想從起始向量平滑的過度到終止向量,那么中間的向量就可以通過插值的方式得到。
這在圖形學中圖形旋轉或者機器人中物體姿態旋轉都可以用到。
有三種方法:Lerp,NLerp和SLerp。
Lerp為線性插值,公式如下:
NLerp為線性插值后歸一化,公式如下:
SLerp為球面插值,公式如下:
公式中的v0和v1就在起始與結束向量,換成四元數同理。
t為插值的中間值,球面插值中theta為兩個向量間的夾角。
實現代碼如下:
clear all; close all; clc; v1=[1 2 3]; %起始向量 v2=[4 -5 -6]; %終止向量 %轉為單位向量 nv1 = v1/norm(v1); nv2 = v2/norm(v2); %畫出起始終止向量 quiver3(0,0,0,nv1(1),nv1(2),nv1(3)); hold on; quiver3(0,0,0,nv2(1),nv2(2),nv2(3)); %起始終止向量轉為四元數 x = nv1(1);y=nv1(2);z=nv1(3); q1 = angle2quat(x,y,z); x = nv2(1);y=nv2(2);z=nv2(3); q2 = angle2quat(x,y,z); %計算向量夾角 w = acos(sum(nv1.*nv2)); figure; %四元數插值 for t=0:0.1:1 q = sin((1-t)*w)/sin(w)*q1 + sin(t*w)/sin(w)*q2; %球面插值 slerp % q = (1-t)*q1 + t*q2; %一般插值 lerp % q = q/norm(q); %一般插值歸一化 nlerp [x,y,z] = quat2angle(q); l=[x y z]; x = x/norm(l); y = y/norm(l); z = z/norm(l); quiver3(0,0,0,x,y,z); hold on; end figure; %向量插值 for t=0:0.1:1 q = sin((1-t)*w)/sin(w)*nv1 + sin(t*w)/sin(w)*nv2; %球面插值 slerp % q = (1-t)*nv1 + t*nv2; %一般插值 lerp % q = q/norm(q); %一般插值歸一化 nlerp quiver3(0,0,0,q(1),q(2),q(3)); hold on; end
結果如下:
初始兩個向量:
四元數球面插值:
向量球面插值:
向量直接插值:
從效果上看,向量球面插值應該是最好的,向量直接插值在轉動角較大的時候無法均勻插值。
網上很多插值都是通過四元數球面插值來做的,看結果並不是很均勻,可能是我這里用法不對?還請知道的人解釋一下。