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)
相关推荐
一隅论数智2 小时前
RDF(Resource Description Framework)介绍和使用举例(二)
大数据·人工智能·经验分享·笔记·学习·架构·政务
小师兄吃牛肉2 小时前
Ansys Electronics 2026 专业仿真平台全面安装解析:核心模块、新增特性与典型应用场景深度指南
笔记
海绵宝宝转agent11 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
91刘仁德14 小时前
HTTP协议详解:从URL到HTTP服务器的完整实战
服务器·网络·笔记·网络协议·http
柳鲲鹏16 小时前
老电脑X99安装WIN11 26H2总结、问题解决办法汇总
笔记
sunoo-22919 小时前
【ARM嵌入式学习笔记第十天】i.MX6ULL eLCDIF控制器驱动RGB LCD全解析(硬件原理+寄存器配置+裸机代码)
arm开发·笔记·学习
听风若依20 小时前
数据在内存中的存储-纸面笔记整理
c语言·笔记
xiaominngtongxue20 小时前
从中职技能节看实训教学的组织逻辑
笔记
杨逢昌工厂6S管理21 小时前
109-杨逢昌车间管理负熵循环:三环体系持续输出负熵的机制解析
经验分享·笔记·职场和发展·学习方法