3D中的旋转变换
相比 2D 中的旋转变换,3D 中的旋转变换复杂了很多。关于 2D 空间的旋转,可以看这篇文章。本文主要粗略地探讨一下 3D 空间中的旋转。
旋转的要素
所谓旋转要素就是说,我们只有知道了这些条件,才知道怎么旋转一个物体。回忆 2D 空间中的旋转,我们需要确定旋转中心、旋转角以及旋转方向才能旋转一个图形。以此类推,到了 3D 空间,我们仍然需要确定三个要素:一个旋转轴、旋转角以及旋转方向。
下面,为了讲解的方便,旋转方向默认为:正对旋转轴正方向,按逆时针方向为旋转正方向,反之为旋转负方向。
旋转的几种情况
3D 中的旋转本质上可以分为下面三类情况:
- 绕 x / y / z 轴旋转;
- 绕通过原点的直线旋转;
- 绕不通过原点的直线旋转。
可能有同学不理解为什么要分这么多情况讨论,其实这是一个将复杂的问题简单化的过程。在旋转 2D 空间中的物体时,我们也只是计算出绕原点旋转的公式,然后将旋转点平移到跟原点重合,再根据公式旋转物体,最后再平移回去。其实完全可以计算出一个绕任意轴旋转的通用公式,但那样会导致计算量更大。
绕 x / y / z 轴旋转
这是最简单的旋转情况,只要把 2D 中的旋转延伸到 3D 空间就可以了。
绕 x 轴旋转

上图是一个绕 x 轴旋转的图示。假设我们需要从点(\(x, y, z\))绕 x 轴旋转 \(\theta\) 角到点 (\(x^,, y^,, z^,\)),那么,旋转过程中,x 的坐标值始终都是固定不变的,因此,我们可以把它当作是在\(x=x^,\)这个平面上进行旋转,从而退化成一个 2D 旋转的问题。
上图右边的两个矩阵,上面那个是 2D 旋转矩阵,而底下那个只是把该矩阵延伸到 3D 空间而已(为了将平移也纳入矩阵运算,3D 的变换都是采用齐次坐标)。因为 x 轴是旋转轴,因此实际上是在 yoz 平面上做 2D 旋转。只要你知道 2D 空间那个旋转矩阵怎么计算,3D 的变换只是依葫芦画瓢而已。
绕 y 轴旋转
同理,这里不再赘述。

绕 z 轴旋转
同理,这里不再赘述。

绕通过原点的直线旋转
以下所引用的例子来自文末链接三维空间中的旋转:旋转矩阵、欧拉角
现在,假设我们要绕旋转轴 \(P\) 旋转 \(\theta\) 角(如下图所示),那又该如何?

目前我们已有的工具只是绕 x / y / z 轴旋转的矩阵而已。回想 2D 中绕任意点旋转的情况,我们是将任意点变换到原点,绕原点旋转后,再变换回原来的位置。所以,同样的道理,这次我们也将绕 \(P\) 轴的旋转分解为三步(跟原文例子的解释稍有不同,但本质上是一样的):
- 将 \(P\) 轴旋转到与 z 轴重合,此时物体跟着旋转到新位置;
- 让物体绕 z 轴旋转 \(\theta\) 角(可以直接套用之前的矩阵);
- 将物体逆向旋转回原来的位置。
下面就针对这三步,解释一下具体的操作。
(1) 首先是将旋转轴旋转到与 z 轴重合。为此,我们需要将 \(P\) 轴绕 z 轴旋转 \(\psi\) 角(根据前面的声明,这里是正方向)。因此,需要乘以矩阵:
\[
R_z(\psi)=\begin{bmatrix} cos\psi & -sin\psi & 0 & 0 \\ sin\psi & cos\psi & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
\]
旋转完后,\(P\) 轴落入 xoz 平面,然后,按照同样的思路,绕 y 轴旋转 \(\phi\) 角,再乘以矩阵:
\[
R_y(\phi)=\begin{bmatrix} cos\phi & 0 & -sin\phi & 0 \\ 0 & 1 & 0 & 0 \\ sin\phi & 0 & cos\phi & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
\]
这时,\(P\) 轴与 z 轴已经重合了。
(2) 然后我们让物体绕 z 轴旋转 \(\theta\) 角:
\[
R_z(\theta)=\begin{bmatrix} cos\theta & -sin\theta & 0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}
\]
(3) 最后,将物体旋转回之前的位置。具体做法是乘以之前矩阵的逆矩阵。至此,我们得到物体旋转所需要的最终矩阵:
\[
R(\theta)=R_z(-\psi)R_y(-\phi)R_z(\theta)R_y(\phi)R_z(\psi)
\]
利用旋转矩阵的性质:\(R(-\alpha)=R^{-1}(\alpha)=R^T(\alpha)\),我们也可以写成:
\[
R(\theta)=R_z^T(\psi)R_y^T(\phi)R_z(\theta)R_y(\phi)R_z(\psi)
\]
绕不通过原点的直线旋转
有了上面的基础作铺垫,这种情况将变得十分简单。只要将旋转轴平移到经过原点的位置,那么问题就转换成上面的情况,最后再平移回去就可以了。因此,变换矩阵只是在上一种情况的基础上,乘上平移矩阵:
\[
R(\theta)=T(x_1, y_1, z_1)R_z^T(\psi)R_y^T(\phi)R_z(\theta)R_y(\phi)R_z(\psi)T(-x_1, -y_1, -z_1)
\]
参考
- Interactive Computer Graphics - A Top-Down Approach 6e By Edward Angel and Dave Shreiner (Pearson, 2012)
- 三维空间中的旋转:旋转矩阵、欧拉角
3D中的旋转变换的更多相关文章
- AutoCAD Civil 3D 中缓和曲线的定义
本文对AutoCAD Civil 3D中缓和曲线的定义进行了整理. 原英文网页如下: https://knowledge.autodesk.com/support/autocad-civil-3d/l ...
- 2d,3d中旋转推导
二维绕原点旋转,其实点为(x,y),旋转角度为黄色标注的角度. 推导过程如下: x' = r cos(al+be); y' = r sin(al+be);x '= rcosalcosbe-rsinal ...
- 在Unity 3D中加入Image图片
在Unity 3D中加入Image图片,我在刚开始是加不进去的,为什么呢?因为没有图片,图如下: 原因就是我们没有把图片设置为Script,图片的格式还是默认的那个,这只能作为贴图使用.我们将图片进行 ...
- Unity 3D中的阴影设置
在Unity 3D中,经常需要用到光照阴影,即Directional Light的Shadow,Shadow分为Hard Shadow和Soft Shadow.区别是Soft Shadow的阴影边缘比 ...
- Unity 3D中不得不说的yield协程与消息传递
1. 协程 在Unity 3D中,我们刚开始写脚本的时候肯定会遇到类似下面这样的需求:每隔3秒发射一个烟花.怪物死亡后20秒再复活之类的.刚开始的时候喜欢把这些东西都塞到Update里面去,就像下面这 ...
- 3D数学读书笔记——3D中的方位与角位移
本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...
- Chem 3D中怎么创建立体模型
ChemDraw作为一款很受大家欢迎的化学绘图软件,其在绘制平面化学方面的功能已经非常的强大了,其实它也可以绘制3D图形.Chem 3D就是绘制3D图形的重要组件.而且为了满足不同的用户绘图的需求,可 ...
- 在3D中两条射线的相交性检测
摘自[3D数学基础: 图形与游戏开发] 考虑在3D中两条以参数形式定义的射线: \(\vec{r_1}(t_1)=\vec{p_1}+t_1\vec{d_1}\) \(\vec{r_2}(t_2)=\ ...
- WPF 3D中多个模型如何设置某一个在最前?
原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...
随机推荐
- 一个关于finally和return的面试题
public class Test{ public int add(int a,int b){ try { return a+b; } catch (Exception e) { System.out ...
- 【Mac进销存管理软件】Daily Sales Pro Mac
[简介] Daily Sales Mac版是Mac平台上的一款进销存软件,库存管理系统.Daily Sales Mac版是一款易于使用的进出库存管理软件,让您及时了解库存状况.销售收入.采购成 ...
- jmeter计算身份证校验位
idcard_no='111111198101017000' ; idcard_no_array = idcard_no.substring(0,17).toCharArray(); int[] c ...
- Redis Bgrewriteaof 命令
一.背景 1. AOF: Redis的AOF机制有点类似于Mysql binlog,是Redis的提供的一种持久化方式(另一种是RDB),它会将所有的写命令按照一定频率(no, always, eve ...
- HDFS 读写数据流程
一.上传数据 二.下载数据 三.读写时的节点位置选择 1.网络节点距离(机架感知) 下图中: client 到 DN1 的距离为 4 client 到 NN 的距离为 3 DN1 到 DN2 的距离为 ...
- zookeeper安装(集群)
Dubbo 建议使用Zookeeper 作为服务的注册中心.Zookeeper 集群中只要有过半的节点是正常的情况下,那么整个集群对外就是可用的.正是基于这个特性,要将ZK 集群的节点数量要为奇数(2 ...
- C语言:使用结构体和指针函数实现面向对象思想(OO编程)
原文:https://www.linuxidc.com/Linux/2016-12/138789.htm 有关:<C语言:过年回家 发现只有我没有对象> 一.基础研究 观察如下两个程序a. ...
- HDU 1026(迷宫 BFS+打印)
题意是要穿过一个迷宫并且将每一步打印出来. 用宽搜的方法找到路径,在 vis 中存一下方向,只是这题被看到的一种不太对的运算符重载坑了很久...... 代码如下: #include <bits/ ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理(附源码)
前言:时间很快,已经快到春节的时间了,这段时间由于生病,博客基本没更新,所以今天写一下我们做的一个项目吧,是对权限的基本操作的操作,代码也就不怎么说了,直接上传源码和图片展示,下面我们直接进入主题介绍 ...
- 他山之石--机器学习 step by step
练习使用的数据 diabetes.csv 备用百度网盘地址 输入变量与输出变量均为连续变量的预测问题是回归问题: 输出变量为有限个离散变量的预测问题成为分类问题: 其实回归问题和分类问题的本质一样,都 ...