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

关于三维空间中的旋转,我们以前提到过基于欧拉角的旋转表达矩阵,它们分别描述了围绕 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 上的正交投影,因此我们可以得出:
v / / ⃗ = ∣ v ⃗ ∣ u ⃗ ⋅ v ⃗ ∣ u ⃗ ∣ ⋅ ∣ v ⃗ ∣ ⋅ u ⃗ ∣ u ⃗ ∣ = u ⃗ ⋅ v ⃗ ∣ u ⃗ ∣ 2 u ⃗ = ( u ⃗ ⋅ v ⃗ ) u ⃗ \vec{v_{//}}=|\vec{v}|\frac{\vec{u}\cdot\vec{v}}{|\vec{u}|\cdot|\vec{v}|}\cdot\frac{\vec{u}}{|\vec{u}|}\\ =\frac{\vec{u}\cdot\vec{v}}{|\vec{u}|^2}\vec{u}\\ =(\vec{u}\cdot{\vec{v}})\vec{u} v// =v u v u v u u =u 2u v u =(u v )u
然后,我们运用向量减法给出 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)

四元数与三维旋转

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值