4元数(转)

2023-10-26

这是国内找不到的超好文章。(为什么大陆的4元数文章很垃圾呢?)
(翻译中。。。奉献给大家~~)

70秒即懂,能使用,用四元数,4元数,阔特尼恩,Quaternion旋转
(C) 中田  亨  (独立行政法人  产业技术综合研究所  数字人类研究中心  研究员 博士(工学))
2003年11月25日

★这个页面的对象读者
想把三次元的旋转,用CG等定量地处理的人
使用欧拉角(Euler Angles)的话,不懂得其道理的人
卡尔丹角和欧拉角(Cardan Angles)不能区别的人
对吉恩瓦尔洛克很困惑的人
但是,对数学之类麻烦的事情很讨厌的人
想要实例程序的人
没有时间的人

★旋转篇:
 我将说明使用了四元数(si yuan shu, quaternion)的旋转的操作步骤
(1)四元数的虚部,实部和写法
所谓四元数,就是把4个实数组合起来的东西。
4个元素中,一个是实部,其余3个是虚部。
比如,叫做Q的四元数,实部t而虚部是x,y,z构成,则像下面这样写。
Q = (t; x, y, z)
又,使用向量 V=(x,y,z),
Q = (t; V) 
也可以这么写。

正规地用虚数单位i,j,k的写法的话,
Q = t + xi + yj + zk
也这样写,不过,我不大使用

(2)四元数之间的乘法
虚数单位之间的乘法
ii = -1, ij = -ji = k (其他的组合也是循环地以下同文)
有这么一种规则。(我总觉得,这就像是向量积(外积),对吧)
用这个规则一点点地计算很麻烦,所以请用像下面这样的公式计算。

A = (a; U)
B = (b; V)
AB = (ab - U·V; aV + bU + U×V)
不过,“U·V”是内积,「U×V」是外积的意思。
注意:一般AB<>BA所以乘法的左右要注意!

(3)3次元的坐标的四元数表示
如要将某坐标(x,y,z)用四元数表示,
P = (0; x, y, z)
则要这么写。
 
另外,即使实部是零以外的值,下文的结果也一样。用零的话省事所以我推荐。

(4)旋转的四元数表示
以原点为旋转中心,旋转的轴是(α, β, γ)
(但 α^2 + β^2 + γ^2 = 1),
(右手系的坐标定义的话,望向向量(α, β, γ)的前进方向反时针地)
转θ角的旋转,用四元数表示就是,
Q = (cos(θ/2); α sin(θ/2), β sin(θ/2), γ sin(θ/2))
R = (cos(θ/2); -α sin(θ/2), -β sin(θ/2), -γ sin(θ/2))
(另外R 叫 Q 的共轭四元数。)

那么,如要实行旋转,
则 R P Q = (0; 答案)

请像这样三明治式地计算。这个值的虚部就是旋转之后的点的坐标值。
 (另外,实部应该为零。请验算看看)

/// Quaternion.cpp
/// (C) Toru Nakata, toru-nakata@aist.go.jp
/// 2004 Dec 29
 
#include <math.h>
#include <iostream.h>
 
/// Define Data type
typedef struct
{
   double t; // real-component
   double x; // x-component
   double y; // y-component
   double z; // z-component
} quaternion;
 
 
Kakezan
quaternion Kakezan(quaternion left, quaternion right)
{
 quaternion ans;
 double d1, d2, d3, d4;

 d1 =  left.t * right.t;
 d2 = -left.x * right.x;
 d3 = -left.y * right.y;
 d4 = -left.z * right.z;
 ans.t = d1+ d2+ d3+ d4;

 d1 =  left.t * right.x;
 d2 =  right.t * left.x;
 d3 =  left.y * right.z;
 d4 = -left.z * right.y;
 ans.x =  d1+ d2+ d3+ d4;

 d1 =  left.t * right.y;
 d2 =  right.t * left.y;
 d3 =  left.z * right.x;
 d4 = -left.x * right.z;
 ans.y =  d1+ d2+ d3+ d4;

 d1 =  left.t * right.z;
 d2 =  right.t * left.z;
 d3 =  left.x * right.y;
 d4 = -left.y * right.x;
 ans.z =  d1+ d2+ d3+ d4;
             
              return ans;
}
 
Make Rotational quaternion
quaternion MakeRotationalQuaternion(double radian, double AxisX, double AxisY, double AxisZ)
{
 quaternion ans;
 double norm;
 double ccc, sss;

 ans.t = ans.x = ans.y = ans.z = 0.0;

 norm = AxisX *  AxisX +  AxisY *  AxisY +  AxisZ *  AxisZ;
 if(norm <= 0.0) return ans;

 norm = 1.0 / sqrt(norm);
 AxisX *= norm;
 AxisY *= norm;
 AxisZ *= norm;

 ccc = cos(0.5 * radian);
 sss = sin(0.5 * radian);

 ans.t = ccc;
 ans.x = sss * AxisX;
 ans.y = sss * AxisY;
 ans.z = sss * AxisZ;

 return ans;
}
 
Put XYZ into  quaternion
quaternion PutXYZToQuaternion(double PosX, double PosY, double PosZ)
{
 quaternion ans;

 ans.t = 0.0;
 ans.x = PosX;
 ans.y = PosY;
 ans.z = PosZ;

 return ans;
}
 
/ main
int main()
{
 double px, py, pz;
 double ax, ay, az, th;
 quaternion ppp, qqq, rrr;

 cout << "Point Position (x, y, z) " << endl;
 cout << "  x = ";
 cin >> px;
 cout << "  y = ";
 cin >> py;
 cout << "  z = ";
 cin >> pz;
 ppp = PutXYZToQuaternion(px, py, pz);

 while(1)
 {
  cout << "/nRotation Degree ? (Enter 0 to Quit) " << endl;
  cout << "  angle = ";
  cin >> th;
  if(th == 0.0) break;

  cout << "Rotation Axis Direction ? (x, y, z) " << endl;
  cout << "  x = ";
  cin >> ax;
  cout << "  y = ";
  cin >> ay;
  cout << "  z = ";
  cin >> az;


  th *= 3.1415926535897932384626433832795 / 180.0; /// Degree -> radian;

  qqq = MakeRotationalQuaternion(th, ax, ay, az);
  rrr = MakeRotationalQuaternion(-th, ax, ay, az);

  ppp = Kakezan(rrr, ppp);
  ppp = Kakezan(ppp, qqq);

  cout << "/nAnser X = " << ppp.x
      <<  "/n      Y = " << ppp.y
      <<  "/n      Z = " << ppp.z << endl;

 }

 return 0;
}   

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

4元数(转) 的相关文章

  • -ffast-math 可以安全地用于典型项目吗?

    在回答我建议的问题时 ffast math 有评论指出这是危险的 我个人的感觉是 在科学计算之外 是可以的 我还假设严肃的金融应用程序使用定点而不是浮点 当然 如果你想在你的项目中使用它 最终的答案是在你的项目上测试它 看看它有多大影响 但
  • 全局变量不好

    好吧 读完这篇文章和一些示例后 我仍然不清楚全局变量的含义 那么你的类中的私有变量是全局的吗 http www c2 com cgi wiki GlobalVariablesAreBad http www c2 com cgi wiki G
  • std::map find 在 C++ 中不起作用[重复]

    这个问题在这里已经有答案了 我使用以下几行创建了一个哈希映射和一个迭代器 std map
  • 地图类容器的专用功能

    我想要专门为矢量和地图之类的容器设计一个函数模板 对于向量 我可以像下面那样做 但我不知道如何才能有一个专门版本的函数 该函数仅用于像地图这样的容器 include
  • 处理器关联组 C#

    我使用的是 72 核的 Windows Server 2016 我看到有两组处理器 我的 net 应用程序将使用一个或其他组 我需要能够强制我的应用程序使用我选择的组 我看到下面的代码示例 但我无法使其工作 我可能传递了错误的变量 我希望应
  • 没有配置身份验证处理程序来处理该方案

    这是一个非常烦人的问题 我在我的 asp net core 项目上设置 cookie 身份验证 有时会出现此错误 有时不会 没有图案 它只是开始抛出错误 然后突然停止 然后再次开始 例外情况是 InvalidOperationExcepti
  • 如何配置 Ninject 来注入 NodaTime IClock

    在我的 NinjectConfigurator 中我有 container Bind
  • 字符串/分段错误

    Program to calculate trip and plan flights define TRIP 6 define NAMEMAX 40 define DEST 1 include
  • 如何在单例类和未命名类之间进行选择?

    我会使用这样的单例 Singleton single Singleton instance single gt do it 我会使用这样的未命名类 single do it 我觉得单例模式除了具有可读的错误消息之外 与未命名的类相比没有任何
  • 在编译输出中添加程序集绑定 (app.config)

    如果我编译应用程序 则会在输出中自动添加程序集绑定 具体的程序集绑定不在app config在 Visual Studio 中但在创建的应用程序配置中 有什么办法可以检查为什么会自动添加程序集绑定吗 选项AutoGenerateBindin
  • 绑定集合的子集

    我有一个ObservableCollection
  • Qt 多重继承和信号

    由于 QObject 我在 QT 中遇到了有关多重继承的问题 我知道很多人也有同样的问题 但我不知道该如何解决 class NavigatableItem public QObject Q OBJECT signals void desel
  • 如何使用 itextsharp 更改 PDF 公式的按钮图标?

    我目前正在尝试使用 itextsharp 填写预定义的表单 除了添加图像之外 一切正常 这之前已经在 Adob e 的 FDF 工具包中运行过 该工具包已编译为 NET 1 1 这不再适用于 NET 4 0 我改用了 itextsharp
  • Microsoft Visual Studio 2017 中的 wxWidgets 设置

    我花了大约 20 个小时试图弄清楚如何在 Microsoft Visual Studio 2017 中设置 wxWidgets 我遵循 https wiki wxwidgets org Microsoft Visual C 2B 2B Gu
  • C 中的等效 plpgsql 触发器

    我有一个 PostgreSQL 9 0 服务器 并且在某些表上使用继承 因此我必须通过如下触发器模拟外键 CREATE OR REPLACE FUNCTION othertable before update trigger RETURNS
  • 将“C# 友好类型”名称转换为实际类型:“int” => typeof(int)

    我想得到一个System Type给定一个string指定 原始 类型C 友好名称 基本上与 C 编译器读取 C 源代码时的方式相同 我觉得描述我所追求的最好方式是单元测试的形式 我希望存在一种通用技术 可以使以下所有断言通过 而不是尝试对
  • 为什么在一行中使用这个 C++ 函数两次会导致编译错误?

    我在尝试在 Visual C 2010 中实现智能相等测试宏类型模板函数时遇到了一些麻烦 该函数与VS 中关于模板函数默认参数的错误 https stackoverflow com questions 10343177 why do i g
  • C# 使用 .Equals() 比较两个 double

    我使用 ReShaper 当我用 比较两个双精度值时 它建议我应该使用 Math 具有公差的 ABS 方法 看 https www jetbrains com help resharper 2016 2 CompareOfFloatsByE
  • 在派生类中访问基类变量

    class Program static void Main string args baseClass obj new baseClass obj intF 5 obj intS 4 child obj1 new child Consol
  • 获取线段上最接近另一个点的点[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我想找到线段AB上最接近另一个点P的点 我的想法是 Get a1 and b1由直线公式y1 a1x b1 使用 A 点

随机推荐

  • html点击显示语音波浪,html5鼠标点击按钮波纹动画特效

    特效描述 html5 鼠标点击 按钮波纹动画 html5按钮波纹动画 代码结构 1 引入CSS 2 引入JS 3 HTML代码 Button A Button B Waves attach flat buttons waves button
  • C++:std::thread:线程用法

    1 std thread的基本用法 最简单的 std thread用法如下 调用 thread将立即同时开始执行这个新建立的线程 新线程的任务执行完毕之后 main 的主线程也会继续执行 include
  • Java中自定义注解的使用

    Java中自定义注解的使用 一般来说 市面上有一些的框架 企业都不会直接拿过来就用 通过会做二次开发或封装 为了更加适配自己的开发规范和业务 那么在封装或适配的过程中 自定义注解就起着比较重要的作用 1 注解定义 原理及作用 1 1 什么是
  • linux qt creator 无法调试

    ubuntu linux操作系统 现象是qt creator 一启动调试 就提示 you can t do that without a process to debug 网上的解答大多是把程序设置成debug模式 但是不生效 下面 介绍解
  • 智能情绪分析技术_视频安防监控系统智能分析技术应用

    本文转自网络 一 概述 在视频监控飞速发展的今天 海量视频画面已经大大超过了人力有效处理的范围 而智能视频分析技术极大地发挥与拓展了视频监控系统的作用与能力 使监控系统具有更高的智能化 大幅度降低资源与人员配置 全面提升安全防范工作的效率
  • java常用类-Math类

    Math类是一个数学工具类方法 里面有很多静态工具方法 方便开发者直接调用 下面列举几个常见的方法 其它方法可查看API文档 public class testMath public static void main String args
  • js中用ajax实现表单提交,Thinkjs使用ajax实现表单提交

    前端代码 1 form submit evt gt evt preventDefault 阻止表单默认提交 ajax url user personal update type POST dataType json data form se
  • 理解FPGA中的亚稳态

    一 前言 大家应该经常能听说到亚稳态这个词 亚稳态主要是指触发器的输出在一段时间内不能达到一个确定的状态 过了这段时间触发器的输出随机选择输出0 1 这是我们在设计时需要避免的 本文主要讲述了FPGA中的亚稳态问题 可以帮助大家更好地理解亚
  • VmWare虚拟机设置ubuntu和windows之间的共享文件夹

    一般在进行编程作业的时候 我们会采用 开发在Windows中编辑源代码 在linux中编译 执行源代码 这往往需要需要将在Windows下编辑好的源代码上传到linux系统种进行编译 怎么来进行上传呢 其实通过VMWare的共享文件夹就可以
  • centos系统出现grub问题修复

    问题 解决方式 1 查看系统分区情况 ls 查看分区 ls hd0 msdos1 查看分区内容 找到存在vmlinuz文件和initramfs文件的分区 操作3步骤 3 grub gt set root hd0 msdos1 将存在vmli
  • echarts(横向柱状图和grid)

    场景 最近在做知识图谱的时候 右侧弹窗需要有数据统计功能 大概 如下图 当时想到的是横向柱状图来实现 目前的效果与UI的不同是后面统计的数量显示的位置 后来经其他前端同事启发 他是用进度条来实现的 发现自己的思想有些死板了 原来进度条实现也
  • VScode中设置vue代码的自动提示&主题

    VScode中设置vue代码的自动提示 下载VueHelper即可 主题推荐 Solarized Light
  • react 阻止默认行为

    react在做某一些弹层的时候 会用到原生的监听点击事件document addEventListener click 这个时候会用到阻止默认事件发生 代码如下 e nativeEvent stopImmediatePropagation
  • 2023linux面试问答_Linux基础

    1 什么是Linux Linux是一套免费使用和自由传播的类Unix操作系统 是一个基于POSIX和Unix 的多用户 多任务 支持多线程和多CPU的操作系统 它能运行主要的Unix工 具软件 应用程序和网络协议 它支持32位和64位硬件
  • 深入随机数Random

    以下内容来自 http www cnblogs com rupeng p 3723018 html 今天再园子上看到了杨老师的一片blog 受益了 原来随机数还有这么多道道 要走的路还远啊 以下为个人收录 几乎所有编程语言中都提供了 生成一
  • windows2008文件服务器端口,windows server 2008 文件服务器不定期出现大量CLOSE_WAIT状态的连接,必须重启服务器,客户端才能访问共享。...

    故障现象如题 用netstat ano p tcp 可以看到大量的连接 都处于close wait状态 然后客户端访问共享就很卡 EXCEL也卡死 服务器重启恢复正常 但是过一段时间又出现这个问题 不知道有谁知道这个问题可能出在哪里 服务器
  • apt-cache - 搜索软件包

    Apt cache是一个命令行工具 可以从本地 APT 文件中查询和显示有关包的可用信息 包信息包括包名称 描述 版本 依赖项 repo 和维护者 存储来自 Debian 镜像的副本的本地 apt 文件位于 var lib apt list
  • day03-switch&循环语句

    1 流程控制语句 应用 在一个程序执行的过程中 各条语句的执行顺序对程序的结果是有直接影响的 所以 我们必须清楚每条语句的执行流程 而且 很多时候要通过控制语句的执行顺序来实现我们想要的功能 1 1 流程控制语句分类 顺序结构 分支结构 i
  • 计算机网络第五章——传输层(下)

    安得广厦千万间 大庇天下寒士俱欢颜 文章目录 按序的不丢失的 这个校验也是二进制求反码来判断有没有发送错误 TCP传输的时候就是以一个字节为单位 所以就会把一个字节编一个序号 对于一个文件第一个需要是多少是可以随机的 发送的时候是以报文段为
  • 4元数(转)

    这是国内找不到的超好文章 为什么大陆的4元数文章很垃圾呢 翻译中 奉献给大家 70秒即懂 能使用 用四元数 4元数 阔特尼恩 Quaternion旋转 C 中田 亨 独立行政法人 产业技术综合研究所 数字人类研究中心 研究员 博士 工学 2