我正在尝试在我的OpenGL程序中从矩阵切换到四元数以进行骨架动画,但我遇到了一个问题:
给定一些单位四元数,我需要得到一个四元数,当用于变换向量时,将给出一个向量,该向量是由每个四元数单独转换的向量的平均值.(使用矩阵我只需将矩阵加在一起并除以矩阵数)
小智 46
与计算机图形行业的普遍看法相反,存在一种直接的算法来解决这个问题,该算法来自航空航天工业,其稳健,准确且简单.它以平均四元数加上(大)常数因子的线性运行.
设Q = [a_1*q_1 a_2*q_2 ... a_n*q_n]
其中a_i是第i个四元数的权重,q_i是被平均的第i个四元数,作为列向量.因此Q是4xN矩阵.
对应于Q*Q ^ T的最大特征值的归一化特征向量是加权平均值.由于Q*Q ^ T是自伴的,并且至少可以获得解决该特征问题的正半确定,快速且稳健的方法.计算矩阵 - 矩阵乘积是随着平均元素数量的增长而增长的唯一步骤.
请参阅2007年"指导,控制和动力学杂志"中的技术说明,该杂志是本方法和其他方法的摘要.在现代,我上面引用的方法对实现可靠性和鲁棒性进行了很好的权衡,并且已经在1978年的教科书中发表了!
Nat*_*one 14
不幸的是,这并不是非常简单,但它是可能的.这是一份解释其背后数学的白皮书:http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872_2007014421.pdf
查看Unity3D Wiki页面(带代码):http://wiki.unity3d.com/index.php/Averaging_Quaternions_and_Vectors
这篇文章也是:http://forum.unity3d.com/threads/86898-Average-quaternions
Gou*_*uda 11
这是 MATLAB函数的实现,我用它来平均四元数的方向估计.将MATLAB转换为任何其他语言是很简单的,除了这种特殊方法(Markley 2007)需要计算特征向量和特征值.有许多库(包括Eigen C++)可以为您完成此任务.
您可以阅读文件的说明/标题,以查看原始论文中的数学.
来自http://www.mathworks.com/matlabcentral/fileexchange/40098-tolgabirdal-averaging-quaternions的 matlab文件:
% by Tolga Birdal
% Q is an Mx4 matrix of quaternions. weights is an Mx1 vector, a weight for
% each quaternion.
% Qavg is the weightedaverage quaternion
% This function is especially useful for example when clustering poses
% after a matching process. In such cases a form of weighting per rotation
% is available (e.g. number of votes), which can guide the trust towards a
% specific pose. weights might then be interpreted as the vector of votes
% per pose.
% Markley, F. Landis, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
% "Averaging quaternions." Journal of Guidance, Control, and Dynamics 30,
% no. 4 (2007): 1193-1197.
function [Qavg]=quatWAvgMarkley(Q, weights)
% Form the symmetric accumulator matrix
A=zeros(4,4);
M=size(Q,1);
wSum = 0;
for i=1:M
q = Q(i,:)';
w_i = weights(i);
A=w_i.*(q*q')+A; % rank 1 update
wSum = wSum + w_i;
end
% scale
A=(1.0/wSum)*A;
% Get the eigenvector corresponding to largest eigen value
[Qavg, ~]=eigs(A,1);
end
Run Code Online (Sandbox Code Playgroud)
小智 5
这是我在 Python 中对 Tolga Birdal 算法的实现:
import numpy as np
def quatWAvgMarkley(Q, weights):
'''
Averaging Quaternions.
Arguments:
Q(ndarray): an Mx4 ndarray of quaternions.
weights(list): an M elements list, a weight for each quaternion.
'''
# Form the symmetric accumulator matrix
A = np.zeros((4, 4))
M = Q.shape[0]
wSum = 0
for i in range(M):
q = Q[i, :]
w_i = weights[i]
A += w_i * (np.outer(q, q)) # rank 1 update
wSum += w_i
# scale
A /= wSum
# Get the eigenvector corresponding to largest eigen value
return np.linalg.eigh(A)[1][:, -1]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23342 次 |
| 最近记录: |