四元数插值Eigen源码解析

news/2025/2/22 1:04:59/

四元数插值公式
Slerp ⁡ ( q 0 , q 1 ; t ) = sin ⁡ [ ( 1 − t ) Ω ] sin ⁡ Ω q 0 + sin ⁡ [ t Ω ] sin ⁡ Ω q 1 , 0 ≤ t ≤ 1 {\displaystyle \operatorname {Slerp} (q_{0},q_{1};t)={\frac {\sin {[(1-t)\Omega }]}{\sin \Omega }}q_{0}+{\frac {\sin[t\Omega ]}{\sin \Omega }}q_{1}}, 0 ≤ t ≤ 1 Slerp(q0,q1;t)=sinΩsin[(1t)Ω]q0+sinΩsin[tΩ]q1,0t1
原理可以看这篇博客
根据公式我们可以比较清晰的分析四元数插值Eigen源码,源码如下所示:

/** \returns the spherical linear interpolation between the two quaternions* \c *this and \a other at the parameter \a t in [0;1].* * This represents an interpolation for a constant motion between \c *this and \a other,* see also http://en.wikipedia.org/wiki/Slerp.*//** * 返回两个四元数之间的球面线性插值* onst Scalar& t : 插值的比例系数,插值时刻距离起始四元数的时间* 占两个四元数时间间隔的多少* other:插值的另一个四元数$q_{1}$**/
template <class Derived>
template <class OtherDerived>
EIGEN_DEVICE_FUNC Quaternion<typename internal::traits<Derived>::Scalar>
QuaternionBase<Derived>::slerp(const Scalar& t, const QuaternionBase<OtherDerived>& other) const
{
// 使用std::acos和std::sinEIGEN_USING_STD_MATH(acos)EIGEN_USING_STD_MATH(sin)// Scalar类型的1,NumTraits<Scalar>::epsilon(),参考这个https://eigen.tuxfamily.org/dox/structEigen_1_1NumTraits.htmlconst Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();// 两个四元数向量的点积,因为四元数的模长都为1所以点积就是夹角的余弦值Scalar d = this->dot(other);/***  如果四元数点积的结果是负值(夹角大于90°),那么后面的插值就会在4D球面上绕远路。* 为了解决这个问题,将余弦值取绝对值保证这个旋转走的是最短路径。**/Scalar absD = numext::abs(d);Scalar scale0;Scalar scale1;
// 如果两个四元数的夹角的cos值接近1的话,为了避免除法出问题,直接算极限 lim_{t->0}{sint/t} = 1if(absD>=one){scale0 = Scalar(1) - t;scale1 = t;}else{// theta is the angle between the 2 quaternions// 计算四元数向量之间夹角Scalar theta = acos(absD);Scalar sinTheta = sin(theta);scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta;scale1 = sin( ( t * theta) ) / sinTheta;}if(d<Scalar(0)) scale1 = -scale1;
// coeffs返回的是以(x,y,z,w)顺序的四元数,因为如果通过double直接对四元数初始化赋值的话它的顺序是(w,x,y,z)return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
}

http://www.ppmy.cn/news/66883.html

相关文章

快速了解 RPC Replication 机制(纯问题版)

1、本次讨论不会明晰底层原理。 2、官方基础知识 : https://docs.unrealengine.com/4.27/zh-CN/InteractiveExperiences/Networking/Actors/ 3、底层原理解析参考文章 : https://zhuanlan.zhihu.com/p/587136954 : https://zhuanlan.zhihu.com/p/590990669 : http://www.aclock…

C语言初阶之三子棋

三子棋 初始文件建立主函数文件棋盘的初始化&#xff08;InitBoard&#xff09;打印棋盘&#xff08;DisplayBoard&#xff09;玩家下棋&#xff08;PlayerMove&#xff09;电脑下棋&#xff08;ComputerMove&#xff09;判定胜负所有代码game.hgame.ctest.c 结语 初始文件建立…

AUTOSAR知识点 之 PDUR (二):ISOLAR-AB配置及代码分析

目录 1、ISOLAR-AB配置 1.1、整体概述 1.2、PduRGeneral 1.3、PduRBswModules 1.4、PduRRountingTabls 2、代码分析 1、ISOLAR-AB配置

Oracle如何修改字符集编码

以下是修改 Oracle 数据库字符集的案例总结&#xff1a; 使用 SELECT * FROM NLS_DATABASE_PARAMETERS p WHERE p.PARAMETERNLS_CHARACTERSET 命令查询当前数据库的字符集。 使用 sqlplus / AS SYSDBA 命令以 SYSDBA 身份登录 Oracle 数据库。 使用 SHUTDOWN IMMEDIATE 命令关…

Linux运行游戏

安装驱动和bumblebee 注意&#xff1a;功能和optimus-manager类似&#xff0c;只需要安装一个。我的电脑安装了optimus-mananger后&#xff0c;导致hibernate后会时不时唤醒卡住无法进桌面 1. 安装软件 sudo pacman -S mesa lib32-mesa vulkan-intel lib32-vulkan-intel # 英…

C++数据结构:哈希 -- unordered系列容器、哈希表的结构以及如何通过闭散列的方法解决哈希冲突

目录 一. unordered系列关联式容器 1.1 unrodered_map和unordered_set 综述 1.2 常见的接口函数&#xff08;以unordered_map为例&#xff09; 1.3 unordered系列与map和set的效率对比 二. 哈希表的底层结构 2.1 什么是哈希 2.2 哈希函数 2.3 哈希冲突 三. 通过闭散列的…

linux安装redis服务

linux环境采用centos7 1.下载redis安装包 官网下载地址&#xff1a;https://redis.io/download/ 2.安装redis依赖 yum install -y gcc tcl3.上传安装包并解压 tar -xzf redis-6.2.12.tar.gz4.编译安装 进入目录下并安装 cd redis-6.2.12 make && make install默认…

在Bamboo上怎么使用iOS的单元测试 | 京东云技术团队

作者&#xff1a;京东零售 吴滔 本教程将使用北汽登录模块为例&#xff0c;一步一步和大家一起搭建单元测试用例&#xff0c;并在Bamboo上跑起来&#xff0c;最终测试结果和代码覆盖率会Bamboo上汇总。 模块名称&#xff1a;BQLoginModule,是通过iBiu创建的一个模块工程 一 建…