Games101课程笔记3--变换

0. 变换分类

两种变换:

一种是模型,另外一种是视图。

1. 变换矩阵

1.1 二维线性变化
  • 缩放

    x′y′\]=\[s00s\]\[xy\] \\begin{bmatrix} x'\\\\y' \\end{bmatrix}= \\begin{bmatrix} s \& 0\\\\0 \& s \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix} \[x′y′\]=\[s00s\]\[xy

  • 反转

    x′y′\]=\[−1001\]\[xy\] \\begin{bmatrix} x'\\\\y' \\end{bmatrix}= \\begin{bmatrix} -1 \& 0\\\\0 \& 1 \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix} \[x′y′\]=\[−1001\]\[xy

  • 切变

    x′y′\]=\[1a01\]\[xy\] \\begin{bmatrix} x'\\\\y' \\end{bmatrix}= \\begin{bmatrix} 1 \& a\\\\0 \& 1 \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix} \[x′y′\]=\[10a1\]\[xy

  • 旋转

    x′y′\]=\[cos⁡θ−sin⁡θsin⁡θcos⁡θ\]\[xy\] \\begin{bmatrix} x'\\\\y' \\end{bmatrix}= \\begin{bmatrix} \\cos \\theta \& -\\sin \\theta\\\\ \\sin \\theta \& \\cos \\theta \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix} \[x′y′\]=\[cosθsinθ−sinθcosθ\]\[xy

上面这些都可以统一表示成

x′y′\]=\[abcd\]\[xy\] \\begin{bmatrix} x'\\\\y' \\end{bmatrix}= \\begin{bmatrix} a \& b\\\\c \& d \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix} \[x′y′\]=\[acbd\]\[xy

我们统称为线性变化

M=abcd M=\begin{bmatrix} a & b\\c & d \end{bmatrix} M=acbd

1.2 平移变化

但是我们发现,我们处理不了平移的这种情况

x′=x+txy′=y+ty x'=x+t_x\\ y'=y+t_y x′=x+txy′=y+ty

我们不想单独处理这种情况,我们想统一放在矩阵中来处理。

于是我们引入了一齐次坐标!

2. 齐次坐标

为了能表示平移,我们多增加了一个维度。

对于2D的点来说它的坐标表示变成了:(x,y,1)⊤(x,y,1)^{\top}(x,y,1)⊤

对于2D的点来说它的向量表示变成了:(x,y,0)⊤(x,y,0)^{\top}(x,y,0)⊤

于是我们可以用下面的方式来表示平移了:

x′y′w=10tx01ty001xyz=x+txy+ty1 \begin{bmatrix} x'\\y'\\w \end{bmatrix}= \begin{bmatrix} 1 & 0 & t_x\\ 0 & 1 & t_y\\ 0 & 0 & 1\\ \end{bmatrix} \begin{bmatrix} x\\y\\z \end{bmatrix}= \begin{bmatrix} x+t_x\\y+t_y\\1 \end{bmatrix} x′y′w = 100010txty1 xyz = x+txy+ty1

对于我们新增的w的理解

vector+vector=vectorpoint−point=vectorpoint+vector=pointpoint+point=point vector + vector = vector\\ point -point = vector\\ point+vector = point\\ point+point = point vector+vector=vectorpoint−point=vectorpoint+vector=pointpoint+point=point

对于ω≠1\omega \ne 1ω=1且不为0的情况

xyw=x/wy/w1 \begin{bmatrix} x\\y\\w \end{bmatrix}= \begin{bmatrix} x/w\\y/w\\1 \end{bmatrix} xyw = x/wy/w1

我们把上面的线性变化和平移变化合起来的变化称为仿射变换

x′y′\]=\[abcd\]\[xy\]+\[txty\] \\begin{bmatrix} x'\\\\y'\\\\ \\end{bmatrix}= \\begin{bmatrix} a \& b\\\\c \& d \\end{bmatrix} \\begin{bmatrix} x\\\\y \\end{bmatrix}+ \\begin{bmatrix} t_x\\\\t_y \\end{bmatrix} \[x′y′\]=\[acbd\]\[xy\]+\[txty

引入齐次坐标

x′y′1=abtxcdty001xy1 \begin{bmatrix} x'\\y'\\1 \end{bmatrix}= \begin{bmatrix} a & b & t_x\\c & d & t_y\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x\\y\\1 \end{bmatrix} x′y′1 = ac0bd0txty1 xy1

3. 变换的组合

3.1 逆变换

跟矩阵的逆一样

B=SAS−1B=A B=SA\\ S^{-1}B=A B=SAS−1B=A

3.2 变换组合

变换的顺序很重要,因为矩阵乘法不可交换

而且我们的变换矩阵的乘是从右往左的。

但是矩阵的乘满足结合律

于是有

An(⋯A2(A1(X)))=(An⋯A2A1)X A_n(\cdots A_2(A_1(X))) = (A_n\cdots A_2A_1) X An(⋯A2(A1(X)))=(An⋯A2A1)X

我们可以预先计算出所有变换矩阵变成一个矩阵

举个例子,如何计算绕任意点旋转?

可以按下面的顺序去计算

  • 我们把这个点移到原点
  • 施加旋转操作
  • 再把这个点移回去

矩阵的形式就像是T(c)R(α)T(−c)T(c)R(\alpha)T(-c)T(c)R(α)T(−c)

注意从右向左!

后面推广到三维的情况就不推了,比较类似。

4. pa0

其实就是个环境搭建

games101主页的给的硬盘打不开,不打了;看了评论区说搞个Eigen库就好了。

还想着用Eigen里的括号初始化,居然要3.4.版本后才支持,默认安装的是3.3.7。

于是把源码拉下来,编译一下

sh 复制代码
cd eigen-3.4.0
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
sudo make install

验证版本对没有

sh 复制代码
pkg-config --modversion eigen3

对了,就可以做pa0的作业:


给定一个点 P=(2,1), 将该点绕原点先逆时针旋转45◦,再平移(1,2), 计算出

变换后点的坐标(要求用齐次坐标进行计算)。

这个其实就是代进旋转矩阵算一下的事,主要检验环境对不对。

cpp 复制代码
    std::cout << "This is my part" << std::endl;
    Eigen::Vector3d point( 2, 1, 1);
    
    
    double theta{M_PI / 4};
    // Example of use Matrix3d
    Eigen::Matrix3d rot {
        { cos(theta), -sin(theta),  1 },
        { sin(theta),  cos(theta),  2},
        { 0,           0,           1}
    };


    Eigen::Vector3d np = rot * point;
    std::cout << rot << std::endl;
    std::cout << "I'm wondering getting a row space?" << std::endl;
    std::cout << np << std::endl; 

还听deepseek改了下cmake的文件

CMakeLists.txt 复制代码
cmake_minimum_required (VERSION 2.8.11)
project (Transformation C CXX)



set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)


#include_directories(EIGEN3_INCLUDE_DIR)



add_executable (Transformation main.cpp)


find_package(Eigen3 3.4 REQUIRED)
target_link_libraries(Transformation Eigen3::Eigen)
相关推荐
沉淀的.晴天21 小时前
ESP32S3笔记
笔记
ss27321 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 28 PostgreSQL MVCC机制介绍
数据库·笔记·postgresql
lll23526917791 天前
2026行业语音转写工具专业术语转写功能横向分析
笔记·智能手机
解决小子1 天前
【虚幻引擎】【C++】【GAS框架】构建角色基类、属性集、数值钳制
c++·笔记·游戏引擎·虚幻·gas·能力系统
破芽1 天前
learn-claude-code-s05-s11-学习笔记
笔记·学习
程序猿乐锅2 天前
【从0-1学习Python | 第七篇】Python 面向对象基础
开发语言·笔记·后端·python·学习·1024程序员节
fish_zzzz2 天前
笔记--浅谈内存,存储空间,BIOS芯片,显卡GPU、VRAM(1)
笔记·1024程序员节
ACP广源盛139246256732 天前
PCIe Gen3 交换芯片选型笔记:多路扩展方案 IX7024@ACP 评估
笔记·硬件架构·pcie·国产芯片
深圳老胡2 天前
STM32 开发中 Trae 内置模型怎么选:Seed、MiniMax、GLM、DeepSeek、Kimi、Qwen 全对比
笔记·stm32·单片机·嵌入式硬件·代码规范·1024程序员节
坤坤子吖2 天前
C++继承:友元、静态成员、多继承与组合
开发语言·c++·笔记·学习·1024程序员节