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元数(转) 的相关文章

  • C++ 令人头疼的命名空间

    好吧 这个问题已经发生了一些变化 我想尝试从我正在追求的基本目标开始 重新 创建在 C 资源获取和初始化中包装遗留 C 语言实体的库代码 并提供基本或更好的异常保证 使此代码的客户端能够以非常自然的 C 方式使用它 而不会为现有代码创建大量
  • 如何在 wpf 密码框设置一些默认文本? [复制]

    这个问题在这里已经有答案了 可能的重复 WPF 中的水印文本框 https stackoverflow com questions 833943 watermark textbox in wpf 我可以知道如何在 WPF 的密码框中放入一些
  • 如何在C++、Qt、QML、Blackberry 10 Cascades Beta 3 SDK中制作图表/图形(如折线图、条形图、圆形图)等?

    我需要知道如何在 Blackberry 10 Cascades Beta 3 SDK QML Qt C 中制作图表 图表 如果有人可以向我展示一个例子或向我指出一些可以告诉我如何做到这一点的东西 我将不胜感激 您应该查看 QChart js
  • 在opencv中保存帧而不压缩

    我正在尝试使用写 OpenCV 函数 我想保存帧 TIFF扩大 我遇到的问题是保存的图像被压缩 所以我无法使用它们 知道如何摆脱这种压缩吗 提前致谢 不要介意西奇说的话 TIFF 标志通过 LZW 压缩硬编码在 opencv 二进制文件中
  • 获取 WSA 错误代码的格式化消息

    我在 win32 C 应用程序中使用winsock2 我将使用 MessageBox 显示可以通过调用 WSAGetLastError 检索的网络错误 我怎样才能做到这一点 我看到 FormatMessage 但我不明白如何使用它 例如 以
  • F1 2019 UDP解码

    我目前正在为 F1 方向盘开发自己的显示器 F1 2019 由codemasters提供 通过UDP发送数据 该数据存储在字节数组中 我在解码返回的数组时遇到一些问题 问题是我得到了很多信息 但我不知道如何处理它们 我将向您介绍我所尝试过的
  • 将 CryptoStream 解密为 MemoryStream

    我编写了一个过程 其中文件被加密并上传到 Azure 然后必须解密下载过程 这会失败并出现 填充无效且无法删除 错误 或 要解密的数据长度为无效的 错误 我在网上尝试了很多解决方案 包括C 使用 RijndaelManaged 和 Cryp
  • 无法使用 MinGW C++ 在 NetBeans IDE 7.3 中编译“Hello World”

    我正在尝试制作一个简单的 Hello World 在 NetBeans IDE 7 3 中使用 MinGW 作为我的 C 编译器来编写程序 我遇到了构建失败的情况 但我不知道为什么 这是我的编译器设置 Family MinGW 基本目录 C
  • 如何创建 .bat 文件来运行 C# 代码?

    我需要的是 我有一个 C 代码 我想构建它以便在桌面上创建一个 bat 文件 因此 当我从桌面运行这个 bat 文件时 它应该执行 C 代码 有没有办法在编译之前更改 c 项目的设置或属性 以便创建应运行此 c 代码的 bat 文件 将 C
  • C# 中的异步方法如何工作?

    我在我的一些项目中使用异步方法 我喜欢它 因为它使我的应用程序更具可扩展性 但是 我想知道异步方法如何在后台真正工作 NET 或 Windows 如何知道调用已完成 根据我进行的异步调用的数量 我可以看到创建了新线程 但并不总是 为什么 此
  • Clang 使用 -nostdlib 生成崩溃代码

    我正在尝试为可执行文件设置自己的运行时环境 但无法使用 clang v3 4 1ubuntu1 目标 x86 64 pc linux gnu 来生成没有段错误的可执行文件 我已将问题简化为以下内容 如果我有一个文件 crt1 c 除了满足
  • 将 size_t 变量添加到指针

    我想向指针添加 size t 类型 有些像这样 void function size t sizeA size t sizeB void pointer pointer malloc sizeA pointer pointer sizeB
  • 委托:方法名称预期错误

    我正在尝试让以下简单的委托示例正常工作 根据我从中取出的一本书 应该没问题 但我得到了Method name expected error namespace TestConsoleApp class Program private del
  • 拦截C# HttpClient GetAsync

    我有一个 Web 项目 C MVC5 但没有 WebAPI 和一个简单的 HTTP REST 客户端 该客户端调用外部 REST 服务并获取 accessToken 等 我想检查所有 Get PostAsync 调用对 statusCode
  • 如何使用 GCC 在 C 上编译库?

    我用这些文件创建了一个库pila h and pila c 我编译文件pila c with gcc pila c c这个库运行良好 我已经测试过了 然后我又做了一个图书馆 这个库有文件pila funciones extra h and
  • GridView,在代码中添加标题行第 2 部分

    这是这篇文章的延续 但添加了完整的代码 ASP NET GridView 在代码中添加标题行 https stackoverflow com questions 19119004 asp net gridview adding header
  • 对 MFC UI 应用程序进行单元测试吗?

    如何对大型 MFC UI 应用程序进行单元测试 我们有一些大型 MFC 应用程序已经开发了很多年 我们使用一些标准的自动化 QA 工具来运行基本脚本来检查基础知识 文件打开等 这些由 QA 小组在日常构建后运行 但我们希望引入一些程序 以便
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 有C语言的解释器吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话
  • 为什么我能够使用无效的类指针进行函数调用

    在下面的代码片段中 虽然指针未初始化 但调用仍然成功 temp ptr ptr gt func2 是C 语言特性的问题 还是VC 6编译器的作弊 class temp public temp a 9 int func1 return a b

随机推荐

  • 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