罗德里格旋转公式 (Rodrigues’ Rotation Formula)

news2024/9/26 3:30:55

关于三维空间中的旋转,我们以前提到过基于欧拉角的旋转表达矩阵,它们分别描述了围绕 x 轴、y 轴、z 轴旋转后坐标应当如何变化。事实上,我们可以更进一步,推导出一个通用的、围绕过原点的任意轴旋转的公式。

题设

这一节我们来描述我们已知的条件和待求的目标:

给定一个方向向量 u ⃗ \vec{u} u 作为旋转轴, v ⃗ \vec{v} v 为待旋转的向量,我们希望得到 v ⃗ \vec{v} v 围绕着 u ⃗ \vec{u} u 逆时针旋转 θ \theta θ角度之后的向量 v ′ ⃗ \vec{v'} v 。注意, v ′ ⃗ \vec{v'} v 的表达式必须用已知条件 u ⃗ \vec{u} u v ⃗ \vec{v} v θ \theta θ来表达。

在这里插入图片描述

思路

旋转前后向量的长度不会变化,反而是如何计算旋转后向量的方向成为了一个难题。我们采用分解向量的思路来解决向量旋转的问题——把 v ⃗ \vec{v} v 分解为平行于 u ⃗ \vec{u} u 的向量 v / / ⃗ \vec{v_{//}} v// 和垂直于 u ⃗ \vec{u} u 的向量 v ⊥ ⃗ \vec{v_\bot} v ,分解的示意图如下:

在这里插入图片描述

这样定义向量的分解方式是有好处的,我们可以发现,旋转前后 v / / ⃗ \vec{v_{//}} v// 没有变化,而旋转前的 v ⊥ ⃗ \vec{v_\bot} v 、旋转后的 v ⊥ ′ ⃗ \vec{v'_\bot} v 都在一个平面内,同一个平面内的旋转比起三维旋转要好解决的多。

公式推导

v / / ⃗ \vec{v_{//}} v// 实际上是 v ⃗ \vec{v} v u ⃗ \vec{u} u 上的正交投影,因此我们可以得出:
KaTeX parse error: Expected 'EOF', got '&' at position 14: \vec{v_{//}}&̲=|\vec{v}|\frac…
然后,我们运用向量减法给出 v ⊥ ⃗ \vec{v_{\bot}} v 的表达式:
v ⊥ ⃗ = v ⃗ − v / / ⃗ \vec{v_{\bot}}=\vec{v}-\vec{v_{//}} v =v v//
接下来,我们需要给出 v ⊥ ′ ⃗ \vec{v'_\bot} v 的表达式。给出一个直观的旋转俯视图:
在这里插入图片描述

先定义 w ⃗ \vec{w} w 。引入这个向量是为了正交分解 v ⊥ ′ ⃗ \vec{v'_\bot} v ,因此它必须垂直于 v ⊥ ⃗ \vec{v_{\bot}} v 。如果你对叉乘很熟悉的话,很快就能想到我们可以用 u ⃗ × v ⃗ \vec{u}\times\vec{v} u ×v 来得到具有这样的性质的向量。注意叉乘的顺序,根据旋转示意图和右手定则, u ⃗ × v ⊥ ⃗ \vec{u}\times\vec{v_{\bot}} u ×v 的向量方向才是俯视图中的 w ⃗ \vec{w} w 方向。

然后,我们把 v ⊥ ′ ⃗ \vec{v'_\bot} v 正交分解成平行于 v ⊥ ⃗ \vec{v_{\bot}} v v v ′ ⃗ \vec{v'_{v}} vv 和平行于 w ⃗ \vec{w} w v w ′ ⃗ \vec{v'_w} vw ,并给出 v ⊥ ′ ⃗ \vec{v'_\bot} v 的表达式。
v ⊥ ′ ⃗ = v v ′ ⃗ + v w ′ ⃗ v v ′ ⃗ = ∣ v ⊥ ⃗ ∣ cos ⁡ θ ⋅ v ⊥ ⃗ ∣ v ⊥ ⃗ ∣ = v ⊥ ⃗ cos ⁡ θ v w ′ ⃗ = ∣ v ⊥ ⃗ ∣ sin ⁡ θ ⋅ u ⃗ × v ⊥ ⃗ ∣ u ⃗ × v ⊥ ⃗ ∣ ∣ u ⃗ × v ⊥ ⃗ ∣ = ∣ u ⃗ ∣ ∣ v ⊥ ⃗ ∣ sin ⁡ ( π / 2 ) = ∣ v ⊥ ⃗ ∣ v w ′ ⃗ = ( u ⃗ × v ⊥ ⃗ ) sin ⁡ θ v ⊥ ′ ⃗ = v ⊥ ⃗ cos ⁡ θ + ( u ⃗ × v ⊥ ⃗ ) sin ⁡ θ \vec{v'_\bot}=\vec{v'_{v}}+\vec{v'_w}\\ \vec{v'_{v}}=|\vec{v_\bot}|\cos\theta\cdot\frac{\vec{v_\bot}}{|\vec{v_\bot}|}=\vec{v_\bot}\cos\theta\\ \vec{v'_w}=|\vec{v_\bot}|\sin\theta\cdot\frac{\vec{u}\times\vec{v_{\bot}}}{|\vec{u}\times\vec{v_{\bot}}|}\\ |\vec{u}\times\vec{v_{\bot}}|=|\vec{u}||\vec{v_{\bot}}|\sin(\pi/2)=|\vec{v_{\bot}}|\\ \vec{v'_w}=(\vec{u}\times\vec{v_{\bot}})\sin\theta\\ \vec{v'_\bot}=\vec{v_\bot}\cos\theta+(\vec{u}\times\vec{v_{\bot}})\sin\theta v =vv +vw vv =v cosθv v =v cosθvw =v sinθu ×v u ×v u ×v =u ∣∣v sin(π/2)=v vw =(u ×v )sinθv =v cosθ+(u ×v )sinθ
上面的式子可以进一步被化简,我们代入 v ⊥ ⃗ \vec{v_{\bot}} v 的表达式,并运用叉乘的分配律:
v ⊥ ′ ⃗ = ( v ⃗ − v / / ⃗ ) cos ⁡ θ + ( u ⃗ × ( v ⃗ − v / / ⃗ ) ) sin ⁡ θ 使用分配律, ( u ⃗ × ( v ⃗ − v / / ⃗ ) ) = u ⃗ × v ⃗ − u ⃗ × v / / ⃗ 因为共线, u ⃗ × v / / ⃗ = 0 v ⊥ ′ ⃗ = v ⃗ cos ⁡ θ − v / / ⃗ cos ⁡ θ + ( u ⃗ × v ⃗ ) sin ⁡ θ \vec{v'_\bot}=(\vec{v}-\vec{v_{//}})\cos\theta+(\vec{u}\times(\vec{v}-\vec{v_{//}}))\sin\theta\\ 使用分配律,(\vec{u}\times(\vec{v}-\vec{v_{//}}))=\vec{u}\times\vec{v}-\vec{u}\times\vec{v_{//}}\\ 因为共线,\vec{u}\times\vec{v_{//}}=0\\ \vec{v'_\bot}=\vec{v}\cos\theta-\vec{v_{//}}\cos\theta+(\vec{u}\times\vec{v})\sin\theta v =(v v// )cosθ+(u ×(v v// ))sinθ使用分配律,(u ×(v v// ))=u ×v u ×v// 因为共线,u ×v// =0v =v cosθv// cosθ+(u ×v )sinθ
最后,我们终于可以给出 v ′ ⃗ \vec{v'} v 的表达式:
v ′ ⃗ = v / / ⃗ + v ⊥ ′ ⃗ v ′ ⃗ = v / / ⃗ + v ⃗ cos ⁡ θ − v / / ⃗ cos ⁡ θ + ( u ⃗ × v ⃗ ) sin ⁡ θ = v ⃗ cos ⁡ θ + ( 1 − cos ⁡ θ ) v / / ⃗ + ( u ⃗ × v ⃗ ) sin ⁡ θ v ′ ⃗ = v ⃗ cos ⁡ θ + ( 1 − cos ⁡ θ ) ( u ⃗ ⋅ v ⃗ ) u ⃗ + ( u ⃗ × v ⃗ ) sin ⁡ θ \vec{v'}=\vec{v_{//}}+\vec{v'_{\bot}}\\ \vec{v'}=\vec{v_{//}}+\vec{v}\cos\theta-\vec{v_{//}}\cos\theta+(\vec{u}\times\vec{v})\sin\theta=\vec{v}\cos\theta+(1-\cos\theta)\vec{v_{//}}+(\vec{u}\times\vec{v})\sin\theta\\ \vec{v'}=\vec{v}\cos\theta+(1-\cos\theta)(\vec{u}\cdot{\vec{v}})\vec{u}+(\vec{u}\times\vec{v})\sin\theta v =v// +v v =v// +v cosθv// cosθ+(u ×v )sinθ=v cosθ+(1cosθ)v// +(u ×v )sinθv =v cosθ+(1cosθ)(u v )u +(u ×v )sinθ
上式的结果即是作为标题而提及的 Rodrigues’ Rotation Formula。

化简为矩阵

我们需要进一步化简公式,得到其等价的矩阵表达形式,才方便代码的实现。

首先,我们需要知道向量三重积公式:
a ⃗ × ( b ⃗ × c ⃗ ) = ( a ⃗ ⋅ c ⃗ ) ⋅ b ⃗ − ( a ⃗ ⋅ b ⃗ ) ⋅ c ⃗ \vec{a}\times(\vec{b}\times\vec{c})=(\vec{a}\cdot\vec{c})\cdot\vec{b}-(\vec{a}\cdot\vec{b})\cdot\vec{c} a ×(b ×c )=(a c )b (a b )c
然后,我们还需要知道,向量的叉乘与矩阵之间的联系:
a ⃗ × b ⃗ = ( y a z b − z a y b z a x b − x a z b x a y b − y a x b ) = A ⋅ b = ( 0 − z a y a z a 0 − x a − y a x a 0 ) ( x b y b z b ) \vec{a}\times\vec{b}=\begin{pmatrix}y_az_b-z_ay_b\\z_ax_b-x_az_b\\x_ay_b-y_ax_b\end{pmatrix}=A\cdot b= \begin{pmatrix} 0 & -z_a & y_a\\ z_a& 0 & -x_a\\ -y_a& x_a & 0 \end{pmatrix}\begin{pmatrix}x_b\\y_b\\z_b\end{pmatrix} a ×b = yazbzaybzaxbxazbxaybyaxb =Ab= 0zayaza0xayaxa0 xbybzb
向量的叉乘可以化为矩阵与向量的乘积,而且需要注意的是,矩阵只与左边的向量有关。


我们化简的目标是得到下述形式的表达式,其中M是矩阵。
v ′ ⃗ = M ⋅ v ⃗ \vec{v'}=M\cdot\vec{v} v =Mv
再次观察公式:
v ′ ⃗ = v ⃗ cos ⁡ θ + ( 1 − cos ⁡ θ ) ( u ⃗ ⋅ v ⃗ ) u ⃗ + ( u ⃗ × v ⃗ ) sin ⁡ θ \vec{v'}=\vec{v}\cos\theta+(1-\cos\theta)(\vec{u}\cdot{\vec{v}})\vec{u}+(\vec{u}\times\vec{v})\sin\theta v =v cosθ+(1cosθ)(u v )u +(u ×v )sinθ
第一项和第三项都可以快速给出等价的矩阵形式,其中, v ⃗ cos ⁡ θ \vec{v}\cos\theta v cosθ可以化为:
v ⃗ cos ⁡ θ = ( cos ⁡ θ 0 0 0 cos ⁡ θ 0 0 0 cos ⁡ θ ) ⋅ v ⃗ \vec{v}\cos\theta=\begin{pmatrix} \cos\theta & 0 & 0\\ 0 & \cos\theta & 0\\ 0 & 0 & \cos\theta \end{pmatrix}\cdot\vec{v} v cosθ= cosθ000cosθ000cosθ v
正如前文所说, ( u ⃗ × v ⃗ ) sin ⁡ θ (\vec{u}\times\vec{v})\sin\theta (u ×v )sinθ也可以化成矩阵乘向量的形式,这里记向量 u ⃗ \vec{u} u 形成的矩阵为 R u R_u Ru,可以得到 ( u ⃗ × v ⃗ ) sin ⁡ θ = R u sin ⁡ θ ⋅ v ⃗ (\vec{u}\times\vec{v})\sin\theta=R_u\sin\theta\cdot\vec{v} (u ×v )sinθ=Rusinθv

比较难以化简的是第二项,处于外部的是向量 u ⃗ \vec{u} u 而不是 v ⃗ \vec{v} v ,这给我们带来了一些麻烦。观察 ( u ⃗ ⋅ v ⃗ ) u ⃗ (\vec{u}\cdot{\vec{v}})\vec{u} (u v )u 这一项和已知的三重积公式,或许可以想办法配凑另外一项,从而把点乘变为叉乘,再运用叉乘的性质化作矩阵。有好几种可能的叉乘式,最终我们选择配凑出这样的叉乘: u ⃗ × ( u ⃗ × v ⃗ ) \vec{u}\times(\vec{u}\times\vec{v}) u ×(u ×v )。其中一个理由是 u ⃗ \vec{u} u 都在左边,我们可以复用前面提到的矩阵 R u R_u Ru;另一个理由是缺失的那一项很好配凑:
u ⃗ × ( u ⃗ × v ⃗ ) = ( u ⃗ ⋅ v ⃗ ) u ⃗ − ( u ⃗ ⋅ u ⃗ ) v ⃗ = ( u ⃗ ⋅ v ⃗ ) u ⃗ − v ⃗ \vec{u}\times(\vec{u}\times\vec{v})=(\vec{u}\cdot\vec{v})\vec{u}-(\vec{u}\cdot\vec{u})\vec{v}=(\vec{u}\cdot\vec{v})\vec{u}-\vec{v} u ×(u ×v )=(u v )u (u u )v =(u v )u v
明确了目标之后,开始化简:
v ⃗ cos ⁡ θ + ( 1 − cos ⁡ θ ) ( u ⃗ ⋅ v ⃗ ) u ⃗ = v ⃗ cos ⁡ θ + v ⃗ − v ⃗ = v ⃗ − ( 1 − cos ⁡ θ ) v ⃗ + ( 1 − cos ⁡ θ ) ( u ⃗ ⋅ v ⃗ ) u ⃗ = v ⃗ + ( 1 − cos ⁡ θ ) ( ( u ⃗ ⋅ v ⃗ ) u ⃗ − v ⃗ ) = v ⃗ + ( 1 − cos ⁡ θ ) ( u ⃗ × ( u ⃗ × v ⃗ ) ) \vec{v}\cos\theta+(1-\cos\theta)(\vec{u}\cdot{\vec{v}})\vec{u}=\vec{v}\cos\theta+\vec{v}-\vec{v}=\vec{v}-(1-\cos\theta)\vec{v}+(1-\cos\theta)(\vec{u}\cdot{\vec{v}})\vec{u}\\ =\vec{v}+(1-\cos\theta)((\vec{u}\cdot{\vec{v}})\vec{u}-\vec{v})\\ =\vec{v}+(1-\cos\theta)(\vec{u}\times(\vec{u}\times\vec{v})) v cosθ+(1cosθ)(u v )u =v cosθ+v v =v (1cosθ)v +(1cosθ)(u v )u =v +(1cosθ)((u v )u v )=v +(1cosθ)(u ×(u ×v ))
我们再次利用叉乘转换为矩阵的性质,可以得到:
u ⃗ × ( u ⃗ × v ⃗ ) = u ⃗ × ( R u ⋅ v ⃗ ) = R u 2 ⋅ v ⃗ \vec{u}\times(\vec{u}\times\vec{v})=\vec{u}\times(R_u\cdot\vec{v})=R_u^2\cdot\vec{v} u ×(u ×v )=u ×(Ruv )=Ru2v
最后我们得到了一个比较复杂的矩阵:
v ′ ⃗ = v ⃗ + ( 1 − cos ⁡ θ ) ⋅ R u 2 ⋅ v ⃗ + R u sin ⁡ θ ⋅ v ⃗ 记 I 为单位矩阵 v ′ ⃗ = ( I + ( 1 − cos ⁡ θ ) ⋅ R u 2 + R u sin ⁡ θ ) ⋅ v ⃗ M = I + ( 1 − cos ⁡ θ ) ⋅ R u 2 + R u sin ⁡ θ \vec{v'}=\vec{v}+(1-\cos\theta)\cdot R_u^2\cdot\vec{v}+R_u\sin\theta\cdot\vec{v}\\ 记I为单位矩阵\\ \vec{v'}=(I+(1-\cos\theta)\cdot R_u^2+R_u\sin\theta)\cdot\vec{v}\\ M=I+(1-\cos\theta)\cdot R_u^2+R_u\sin\theta v =v +(1cosθ)Ru2v +Rusinθv I为单位矩阵v =(I+(1cosθ)Ru2+Rusinθ)v M=I+(1cosθ)Ru2+Rusinθ
M即为我们所求的矩阵。

Refer

罗德里格旋转公式(Rodrigues’ rotation formula)

四元数与三维旋转

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux-网络-nc命令

目录 概述 nc命令常用参数 nc命令示例 实现TCP/UDP侦听 作为client端发起TCP/UDP连接 服务器之间传输文件 网络测速 概述 在centos中,nc命令是ncat的软链接。 ncat是一个功能丰富的网络实用程序,是为nmap项目编写的(Network Mapper&…

12个python超强学习网站!

一、python学习网站 1 CSDN 特点:从免费视频到入门项目,从入门到进阶,学习视频应有尽有,还有Python学习社区,良好的学习和沟通氛围! 2 Python123 地址:python123 特点:北京理工…

适合零基础人群学习的Python入门教程,快来学习吧

适合零基础人群学习的Python入门教程学什么?小编为大家准备的Python学习教程,课程主要讲解:Python核心编程、Linux基础、前端开发、Web开发、爬虫开发、人工智能等内容。 对于初学者想更轻松的学好Python开发,爬虫技术&#xff0c…

个人博客 HTML个人介绍网页 学生个人网页设计作品 学生个人网页模板 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

LeetCode刷题日记之栈与队列II

1.有效的括号 题目描述 解题思路 1.定义一个辅助栈stack来存放字符串,再定义一个以符号最为键、值的对象obj 2.循环遍历字符串,判断栈顶元素对应的key在obj中的值是否等于当前遍历值s[i],如果等于则直接弹栈,不等于则将s[i]值推…

数据结构---判断链表是否有环

判断链表是否有环判断链表是否有环方法1方法2JAVA实现问题扩展1问题扩展2判断链表是否有环 有一个单向链表,链表中有可能出现“环”,就像下图这样。那么,如何用程序来判断该链表是否为有环链表呢? 方法1 创建一个以节点ID为Ke…

大数据Kudu(九):Spark操作Kudu

文章目录 Spark操作Kudu 一、​​​​​​​​​​​​​​添加Maven依赖

【DELM回归预测】基于灰狼算法改进深度学习极限学习机GWO-DELM实现数据回归预测附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

网络请求与数据提取-urllib库

关于网络爬虫,其实就是模拟浏览器向网站服务器发送请求,然后从响应的结果中提取出需要的数据。那么,该如何实现这一流程了?对于初学者来说,可能都不知道该如何入手,学习爬虫时需不需要了解HTTP、TCP、IP 层…

入门:环境安装与部署

容器技术入门 随着时代的发展,Docker也逐渐走上了历史舞台,曾经我们想要安装一套环境,需要花费一下午甚至一整天来配置和安装各个部分(比如运行我们自己的SpringBoot应用程序,可能需要安装数据库、安装Redis、安装MQ等…

springboot常用语法库

今天与大家分享springboot常用语法库的基本语法。如果有问题,望大家指教。 目录 1. freemarker是什么 1.1 优点 2. springboot整合freemarker 2.1 pom.xml 2.2 项目配置文件 2.3 Controller 2.4 index.ftl 2.5 常用功能演示 1. freemarker是什么 FreeMarke…

OPENGL ES 2.0 知识串讲 (3)——SHADER的功能GLSL语法(I)

更多图形知识请关注我的公众号: 在第一节中,我们介绍过 OpenGL ES 与 GLSL 的主要功能,就是往绘制 buffer 上绘制图片。其中虽然 GLSL 制作的 shader 是穿插在 OpenGL ES 中使用,但是我们在流程中可以看出来,两大 shader(vertex shader 和 fragment shader)相对于 O…

大学毕业生就业信息管理平台

开发工具(eclipse/idea/vscode等): 数据库(sqlite/mysql/sqlserver等): 功能模块(请用文字描述,至少200字): 系统在功能设计充分利用信息化技术和互联网的优势,建立一个以浏览器为用户工作界面,实现跨 平台…

Hive电子商务消费行为分析项目

文章目录数据说明环境准备项目代码上传数据文件并创建数据表数据清洗数据可视化客户分析交易分析门店分析评价分析数据说明 某零售企业的门店最近一年收集的数据 customer_details.csv:客户信息 transaction_details.csv:交易信息 store_details.csv:门店信息 store_review.c…

第1章 基础知识简介

🌞欢迎来到C语言的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🌠本阶段属于练气阶段,希望各位仙友顺利完成…

【机器码】原码、反码、补码的学习

目录 让我们看看这三个码是什么 原码、反码、补码各自的范围 补码的加减运算 根据自己学习做的笔记来记录一下 原码、反码、补码,巩固自己的学习成果。 有符号数是由机器数和真值组合而成 真值:数值数据的实际值,带有-符号 …

RL 实践(3)—— 悬崖漫步【QLearning Sarsa 各种变体】

本文介绍如何用 QLeaning 系列和 Sarsa 系列表格方法解经典的悬崖漫步 (Cliff Walking) 问题完整代码下载:4_[Gym Custom] Cliff Walking (Q-Learning series and Sarsa series) 文章目录1. 悬崖漫步环境 (Cliff Walking)2. 使用 TD 方法求解2.1 Sarsa2.1.1 Sarsa 原…

kali 安装AWVS [赠附件]

前言 1.AWVS简介 AWVS(Acunetix Web Vulnerability Scanner)是一款知名的网络漏洞扫描工具,通过网络爬虫测试网站安全,检测流行的Web应用攻击,如跨站脚本、sql 注入等。据统计,75% 的互联网攻击目标是基于…

项目中遇到的错误

项目中遇到的错误swagger2 和 swagger3swagger 文档的注解springboot 版本问题SQL 关键字异常Apifox 的使用集中版本管理swagger2 和 swagger3 swagger2和 swagger3 需要导入的依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfo…

LabVIEW FPGA中可重入和非可重入子VI的区别

LabVIEW FPGA中可重入和非可重入子VI的区别 LabVIEW FPGAVI默认是可重入的。如果多次调用重入VI&#xff0c;则每个实例会占用FPGA器件的单独硬件资源。如果使用非重入VI&#xff0c;无论是并行多次调用还是仅调用一次&#xff0c;都只会创建一个硬件实例并将其用于该VI。 ​…