【线性代数】图形学基础:齐次坐标与矩阵变换

作者:h_a_o777oah日期:2026/7/21

计算机图形学涉及很多知识,比如线性代数和微积分等等。在学习图形学知识前,我们应该要对这些基础知识有一个了解。下面介绍一下相关的基础线性代数知识。

首先我们要知道,线性代数中的矩阵是可以变换坐标系里点的位置的。而比如 分别表示二维或者三维空间中点或者向量的坐标,也可以写成 或者 。如果有对于矩阵乘法不理解的,可以查看我此前的一个矩阵快速幂博客,其中有一段是对于矩阵乘法的解析。链接:【算法详解】矩阵快速幂:如何将线性方程组映射为转移矩阵解决线性递推-CSDN博客

齐次坐标

我们知道,对于一个向量进行平移,它的坐标是不会发生改变的,向量具有平移不变性;但是点却会是改变的。可是,我们对于向量和点却是同一套坐标表示方法,难道我们每次做平移前都需要判断这个是向量还是点吗?这太麻烦了,所以我们发明了齐次坐标的表示方法。

在齐次坐标,我们对于坐标表示增加了一个维度,即在 2 维坐标系表示为 三维坐标系表示为 。如果表示点,则 w=1 ;如果表示向量,则 w=0 。比如说在三维坐标系 表示的就是点 (4,5,3) , 表示的是向量 (4,5,3) 。

而这样表示有什么好处呢?我们可以发现,这样表示的逻辑是合理的。

由上可以发现,点与点相减就变成了向量,完全符合我们的运算法则。而且点与向量相加也是点,相当于点沿着向量方向去移动,结果还是这个点,不过是改变了坐标。而且向量与向量相加也是一个向量。

所以这样表示是完全符合逻辑的。在接下来矩阵变换的平移中,更可以感受到齐次坐标的用处。

矩阵变换

缩放

如果我们想要把一个坐标系里的物体给变大或者缩小,应该怎么办呢?如下图

假设现在是向 x 轴增大 a 倍,向 y 轴方向增大 b 倍。我们可以知道,那对于这个物体里的每一个点,变化后应该都是同样的增大。那我取这个物体里任意一个点 ,那变化完后这个点坐标是 ,可以推导出如下

可以发现其实这个方程组满足矩阵的定义,所以接下来提取出来参数写成矩阵的形式,那就是

我们可以发现,通过一个矩阵乘法,我们就成功的表示出来缩放了。对于后面的每一种矩阵变换,其实都可以类似这样取推导。也是因此,矩阵才可以表示出来坐标的变换。

同理,对于三维坐标,我们想要进行向 x 轴增大 a 倍,向 y 轴方向增大 b 倍,向 z 轴方向增大 c 倍,则可得

写成矩阵形式就是

这个时候其实我们也能发现这个缩放矩阵的基本的形式了。但我们刚刚其实还提到过齐次坐标,如果对于齐次坐标表示的,这个缩放矩阵只需要稍微变换一下。由于无论是点或者是向量,缩放后的 w 都不会改变,所以只需要在方程组里加入一个式子 或者 即可。则可得

二维:

三维:

旋转

如下图,绕原点进行旋转,旋转角 θ 定义为逆时针旋转转过的角度(顺时针取反即可)。

旋转的变换矩阵推导有点麻烦,由于刚刚的缩放的推导大家应该基本理解了为什么矩阵可以表示变换还有如何推导来的,这里直接给出结论吧(右手系)。

二维(绕原点):

三维(绕 x 轴):

三维(绕 y 轴):

三维(绕 z 轴):

齐次坐标表示也很简单,只是在外围加了一圈0,矩阵边角那个地方是 1 而已。

二维(绕原点):

三维(绕 x 轴):

同理可得三维绕 y 轴旋转和绕 z 轴旋转的变换矩阵。

平移

平移是比较特殊的一个变换,正是为了处理平移,我们发明了齐次坐标。我们先来看看,没有齐次坐标我们是如何进行平移的。

我们刚刚可以看到,对于类似缩放和旋转的变换,我们想要从状态 A 变换成状态 A' ,我们只需要乘上一个特定的矩阵 M 即可做到了。

但是,如果我们想要进行平移,比如向 x 方向移动 a 个单位,向 y 方向移动 b 个单位,向 z 方向移动 c 个单位。即

我们发现,后面的 abc 都是常数,根本无法写成一个矩阵。所以,我们只能这样写了。

这样写简直无法让人满意,因为刚刚的缩放和旋转都是乘一个矩阵就可以了,怎么到了这里后面又多了一个加法计算呢。不仅如此,刚刚也提到了我们还需要分辨是向量还是点,向量又不需要加,因为平移不变;点又需要加常数。这样太复杂了,为了统一由一个矩阵表达变换,更是为了不用一直判断点和向量,我们才需要齐次坐标

所以,我们增多一个维度 w 来让平移实现,则方程组变成如下。

这样一来,式子就统一了。w 也属于一个未知数,只不过它的取值是 0 或 1 。而且,**w 取 0 的时候,常数项就是 0 ,完美符合了向量的平移不变性;w 取 1 的时候常数项存在且正好就是系数 abc ,符合点的平移!**所以我们才让 w=0 表示向量,w=1 表示点。

我们写成矩阵形式就是

同理,二维平移的变换矩阵为

总结

可以看到,我们通过齐次坐标还有矩阵变换,我们基本可以描述二维和三维空间里的大部分物体运动了。对于复杂的运动变换,我们可以把它拆解成一个个简单的运动,利用矩阵描述小运动,通过矩阵乘法的结合律来表示一个复杂的运动。

也就是说,对于一个复杂运动矩阵 A ,初状态为 n ,末状态为 n' ,要得到这个运动 A 需要 A_1,A_2,...,A_n 个运动按顺序合成。其实根据矩阵乘法的结合律,可得

注意不能交换顺序,因为矩阵乘法是不满足交换律的。但我们可以通过结合律,算出这个复杂运动矩阵 A 。那样只要任意一个物体想要进行 A 变换,只要一乘这个矩阵就可以了,不再需要我们进行复杂的运动推导。所以图形学才能如此和线性代数的矩阵运算关系紧密,有了矩阵计算机运算速度可以说是加倍了。


【线性代数】图形学基础:齐次坐标与矩阵变换》 是转载文章,点击查看原文


相关推荐


LeetCode 150. 逆波兰表达式求值
Best_Jerry2026/7/13

leetcode.cn/problems/ev… programmercarl.com/0150.%E9%80… 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 '+'、'-'、'*' 和 '/' 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总是 向零截断 。 表达式中不含除零运算。 输入是一个根据逆波兰表示法表示的算术表达式。 答案及所有中间计算结果可


【系统架构设计师】论文篇
忻州人在郑州2026/7/5

文章目录 前言总体方向浅谈论文要求及准备方法如何找项目具体论文各部分准备通用摘要模板通用项目背景与本人职责通用点题句中间段1. 论微服务架构及其应用2. 论云原生架构及其应用3. 论大数据架构及其应用4. 论系统架构评估5. 论软件测试方法及应用6. 论需求分析方法及应用7. 论软件开发模型及应用8. 负载均衡9. 事件驱动架构 万能句1. 需求与变更控制2. 敏捷开发3. 测试保障4. 运维治理 通用结尾 参考资料 前言 ​ 本系列文章为软考系统架构设计师笔记


Flutter版本选择指南:3.44系列继续观望 | 2026年6月
程序员老刘2026/6/27

大家好,我是老刘 每次Flutter发新版本,群里总有人问:"老刘,3.44.3出来了,我能升了吗?" 我的回答永远不变:再等等。 不是我不信任Google的修复速度。事实上,3.44系列这一个月发三个补丁,节奏还算克制。但是,补丁版本的稳定不等于生产环境的可靠,尤其是3.44这一版动了SwiftPM和Android底层架构,第三方插件的适配进度至今没有一个明确的说法。 今天这篇,我把6月所有版本状态、修复内容和选择策略一次性讲清楚,帮你做出不后悔的决定。 一、6月Flutter大事件 Flu


PyCharm 中调用项目内文件夹的 Python 文件方法
6v6-博客网2026/6/18

PyCharm 中调用项目内文件夹的 Python 文件方法 在 PyCharm 中调用另一个文件夹中的 .py 文件,本质上是解决 Python 的模块导入路径问题。默认情况下,Python 只会搜索当前目录和系统库,直接导入子文件夹里的模块会报 ModuleNotFoundError。以下提供三种最有效的解决方案。 方法一:将文件夹标记为「源根」(最推荐) 这是 PyCharm 独有的便捷功能,无需修改代码即可让 IDE 识别路径。 在项目侧边栏中,右键点击目标文件夹(比如 utils)。选


workbuddy ,node.js 每次会在 项目目录上安装 node_modules,能不能一次安装多次使用,为什么 npm 不把包装在全局
zhangfeng11332026/6/10

workbuddy ,node.js 每次会在 项目目录上安装 \node_modules ,而不是把他放到node.js的安装目录 或者系统的path 中导致 ,类似的功能 都要载入 安装 程序包 很慢 你的问题核心是:npm 默认把包安装在项目本地 node_modules,每次新建项目都要重新 npm install,耗时且冗余。这是 npm 的设计哲学问题,我来解释清楚并提供解决方案。 为什么 npm 不把包装在全局? npm 的设计原则是 依赖隔离: 方式优点缺点项目本地安装(


数据同步的几种姿势
小跟班_mya2026/6/3

先搞清楚一件事:为什么要有 ES 数据同步? 想象一下,你开了一家图书馆: MySQL 是图书管理员,负责把书一本本摆好、登记在册(增删改查、事务保证)Elasticsearch 是图书检索系统,用户输入"三体",0.01 秒就能告诉你第几排第几架(全文检索、聚合分析) 问题来了:管理员刚上架了一本新书,检索系统怎么立刻知道这本书的存在?这就是数据同步要解决的事。 方案一:同步双写——"一边记账一边贴标签" 场景 你开了个电商网站,用户下单后,订单既要存到 MySQL(方便财务对账


Vibe Coding 全栈实战:章鱼哥解题 07|功能跑通后的架构收敛
小小小小小鹿2026/5/28

Vibe Coding 全栈实战:章鱼哥解题 07|功能跑通后的架构收敛 上一期做完对话持久化以后,章鱼哥已经不只是一个“能回答问题”的接口了。它有了登录态,有了当前对话,有了 LangGraph thread,也能在刷新页面后恢复最近的消息。 但功能跑通以后,我回头看了一下后端模块依赖,发现了两个不太舒服的地方。 一个是 agent 依赖了 chat: agent.nodes → chat.question_classifier 另一个是 infra.llm 依赖了 rag.context_


开发了一个管理本地开发环境的软件
神奇的程序员2026/5/5

前言 前阵子换了新电脑,我在整理本地开发环境时,看到一堆需要重新装的,顿时感觉好麻烦。想着都过去这么久了,应该有工具可以做到统一管理,实现快速安装、更新、切换版本吧。 经过一番查找后,找到了mise这个东西,只需要简单的一句命令就能安装java、node、redis、go等工具,而且还支持对这些工具做统一管理(更新、删除),支持三大主流平台(macOS/Windows/Linux) 命令行始终不方便,于是我萌生了一个做GUI的想法,花了亿点时间用Flutter把它开发出来了,欢迎各位有需要的开发


Hello 算法:“走一步看一步”的智慧
灵感__idea2026/4/26

每个系列一本前端好书,帮你轻松学重点。 本系列来自上海交通大学硕士,华为高级算法工程师 靳宇栋 的 《Hello,算法》 “走一步看一步”,是我们面对不断变化的世界所采取的应对策略。 多数时候,我们无法对未来做出准确预测,只能根据上一件事的结果对下一件事做决策。介绍“分治”的时候,我们已经接触过这种策略。本篇主角依然如此,但又有所不同。 先看个例子。 爬楼梯 给一个 n 阶楼梯,每步可以上 1 阶或者 2 阶,问有多少种方案可以爬到楼顶? 假设 n 是3,那么方案共 3 种。如下图所示。 这


Linux 驱动开发入门:从最简单的 hello 驱动到硬件交互
4. 嵌入式铲屎官2026/4/17

Linux 驱动开发入门:从最简单的 hello 驱动到硬件交互 🎉 写给未来的自己和领导:本文是 Linux 驱动开发的 入门级保姆教程,从零开始搭建驱动框架,逐行解释代码,记录每一个踩过的坑。无论你是刚接触内核编程,还是想快速上手 GPIO 中断,都能在这里找到清晰的思路和可复现的步骤。 📚 目录 引言:驱动是什么?驱动的基本框架 —— 一切皆文件实战:第一个 hello 驱动 3.1 完整的驱动源码(带详细注释)3.2 编译驱动 —— Makefile 解析3.3 上机测试 ——

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读