matlab練習程序(向量插值)


有兩個向量,我們想從起始向量平滑的過度到終止向量,那么中間的向量就可以通過插值的方式得到。

這在圖形學中圖形旋轉或者機器人中物體姿態旋轉都可以用到。

有三種方法: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

結果如下:

初始兩個向量:

 

四元數球面插值:

向量球面插值:

向量直接插值:

從效果上看,向量球面插值應該是最好的,向量直接插值在轉動角較大的時候無法均勻插值。

網上很多插值都是通過四元數球面插值來做的,看結果並不是很均勻,可能是我這里用法不對?還請知道的人解釋一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM