四元数解析

四元数对游戏开发来说是一个绕不过的知识点。四元数之所以比欧拉角好用,是因为四元数没有万向节死锁,并且可以很方便的对旋转轴增量旋转,计算量较小。简单总结一下:

四元数当然由四个部分组成,一般描述为: q = ( x, y, z, w ),其中 x, y, z是复数,具体是:q = { xi,yj,zk, w}

四元数用来表示绕着某个轴旋转,q里面的xyz部分表示旋转轴,w表示旋转的角度。

复数的定义是:i^{2} = -1

共轭复数:

  复数F_{} = a + bi ,那么他的共轭复数是  F^{'} = a - bi,也就是实部相同,虚部取负。

四元数的旋转表示:

有一个三维空间的点w(4,4,4),绕着(1,2,3)的轴旋转30°,计算旋转后的坐标。

第一步:构建四元数。 w = (4,4,4,0)

第二步:构建旋转四元数。 q = ( cos\frac{\Theta }{2} * 1, sin\frac{\Theta }{2} *2,sin\frac{\Theta }{2} *3, 0)

第三部:根据旋转公式得到 W^{'} = q * W * q^{-1}

四元数的旋转公式: W^{'} = q * W * q^{-1}

四元数角度增量是四元数的乘法运算

内容未整理。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
g2o的源码比较复杂,主要分为以下几个部分: 1. core:核心部分,包括图模型(Graph)、顶点(Vertex)、边(Edge)、优化算法(OptimizationAlgorithm)等。 2. solver:求解器部分,包括线性求解器(LinearSolver)、稀疏矩阵(SparseBlockMatrix)、稠密矩阵(DenseBlockMatrix)等。 3. types:类型部分,包括各种图优化问题相关的数据类型,如向量(Vector)、旋转矩阵(SE3)、四元数Quaternion)等。 4. stuff:工具部分,包括文件读写、时间计算、随机数生成、命令行参数解析等。 下面以求解一个简单的图优化问题为例,简单介绍g2o的源码结构和使用方法。 首先,我们需要定义一个图模型,并向模型添加顶点和边。比如,我们可以定义如下的图模型: ```c++ #include <g2o/core/sparse_optimizer.h> #include <g2o/core/block_solver.h> #include <g2o/core/optimization_algorithm_levenberg.h> #include <g2o/solvers/eigen/linear_solver_eigen.h> typedef g2o::BlockSolver<g2o::BlockSolverTraits<2,1>> BlockSolverType; typedef g2o::LinearSolverEigen<BlockSolverType::PoseMatrixType> LinearSolverType; typedef g2o::OptimizationAlgorithmLevenberg OptimizationAlgorithmType; int main(int argc, char** argv) { // 构建图优化模型 g2o::SparseOptimizer optimizer; optimizer.setVerbose(true); // 设置线性求解器和块求解器 LinearSolverType *linearSolver = new LinearSolverType(); BlockSolverType *blockSolver = new BlockSolverType(linearSolver); OptimizationAlgorithmType *optimizationAlgorithm = new OptimizationAlgorithmLevenberg(blockSolver); // 设置求解算法和优化器 optimizer.setAlgorithm(optimizationAlgorithm); // 添加顶点 g2o::VertexSE2 *v1 = new g2o::VertexSE2(); v1->setId(0); v1->setEstimate(g2o::SE2(0,0,0)); optimizer.addVertex(v1); g2o::VertexSE2 *v2 = new g2o::VertexSE2(); v2->setId(1); v2->setEstimate(g2o::SE2(1,0,0)); optimizer.addVertex(v2); // 添加边 g2o::EdgeSE2 *e = new g2o::EdgeSE2(); e->setVertex(0, v1); e->setVertex(1, v2); e->setMeasurement(g2o::SE2(1,0,0)); e->setInformation(Eigen::Matrix3d::Identity()); optimizer.addEdge(e); // 执行优化 optimizer.initializeOptimization(); optimizer.optimize(10); // 输出结果 std::cout << v1->estimate().toVector().transpose() << std::endl; std::cout << v2->estimate().toVector().transpose() << std::endl; return 0; } ``` 在上面的代码,我们首先定义了一个g2o::SparseOptimizer对象,然后设置了线性求解器和块求解器,以及Levenberg-Marquardt优化算法。接着,我们向模型添加了两个顶点和一条边,其边的测量值为(1,0,0),信息矩阵为单位矩阵。最后,我们执行了10次优化,并输出了优化后的顶点估计值。 g2o的源码结构比较复杂,但是其设计思想清晰,代码风格规范,易于扩展和修改。使用g2o库可以快速高效地解决各种图优化问题,是图优化领域不可或缺的工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值