变换

2D变换

  1. 缩放: 每一个轴都做对应的缩放
  2. 缩放矩阵: (sx, 0, 0, sy),坐标左乘缩放矩阵可以得到缩放后的坐标
  3. 反射矩阵: (-1, 0, 0, 1),绕一根轴做镜像操作,让x=-x,y=y
  4. 切变矩阵: (1, a, 0, 1),拽住矩形上边,往右移动a距离,变成平行四边形
  5. 旋转: 按某一个点做逆时针旋转
  6. 旋转矩阵: (cos(θ), -sin(θ), sin(θ), cos(θ))
  7. 旋转矩阵的性质
    1. R(-θ) = (cos(θ), sin(θ), -sin(θ), cos(θ)) = Rθ的转置矩阵
    2. R(-θ) = Rθ的逆矩阵(根据定义)
    3. 旋转矩阵的转置矩阵与逆矩阵相等,所以旋转矩阵也是正交矩阵
  8. 线性变换: x1 = ax + by, x2 = cx + dy,用一个矩阵左乘一个坐标得到新的坐标的变换

齐次坐标系

  1. 为什么需要齐次坐标系: 平移没有办法表示成一个矩阵左乘一个坐标的形式,x1 = x + tx, y1 = y + ty
  2. 齐次坐标如何解决平移问题: 新增一个维度,点坐标变成(x, y, 1), 向量变成(x, y, 0),这样平移矩阵则为(1, 0, tx, 0, 1, ty, 0, 0, 1)
  3. 为什么点和向量的新增维度是1和0: 点新增维度为1,是为了表示点+点=中点,即(x, y, w) => (x/w, y/w, 1),向量新增维度为0,是为了向量的平移不变性,向量左乘平移矩阵还是原向量
  4. 仿射变换: x1 = ax + by + tx, y1 = cx + dy + ty,是线性变换和平移的统称
  5. 逆变换: 将变换后的坐标转换回变换之前的,坐标左乘逆矩阵

变换的组合

  1. 每一次变换都对应着一次左乘,表示为 An * An-1 * ... * A1 * (x, y)
  2. An * An-1 * ... A1得到的矩阵代表了一系列复杂变换的组合,该矩阵缓存起来可以减少计算量

复杂变换的分解

  1. 如何按给定点c进行旋转:先平移到原点,再做旋转,再平移回去,T(c) * R(a) * T(-c)

3D变换

  1. 与2D基本一致,点的坐标多了一个维度(x, y, z, 1)
  2. 4x4的仿射变换矩阵,先应用线性变换,再应用平移
  3. 缩放矩阵: (sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)
  4. 平移矩阵: (1, 0, 0, tx, 0, 1, 0, ty, 0, 0, 1, tz, 0, 0, 0, 1)
  5. 旋转矩阵:
    1. 绕x轴: (1, 0, 0, 0, 0, cos, -sin, 0, 0, sin, cos, 0, 0, 0, 0, 1)
    2. 绕y轴: (cos, 0, sin, 0, 0, 1, 0, 0, -sin, 0, cos, 0, 0, 0, 0, 1)
    3. 绕z轴: (cos, -sin, 0, 0, sin, cos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
    4. 绕任意轴: 先将轴平移至原点,将轴绕z绕y旋转至z轴重合,再绕z旋转指定角度,再按原来的变换做一次逆变换
    5. 罗德里格斯旋转公式: 向量的计算转为矩阵计算
    6. 四元数: 旋转与旋转的插值计算

视图变换

  1. 思考如何拍照?
    1. 选一个好的地方: 模型变换,model transformation
    2. 调整一个好的角度: 视图变换,view transformation
    3. 拍照: 投影变换,projection transformation
  2. 如何提现视图变换?
    1. 相机的位置:position
    2. 相机的朝向:look at direction
    3. 相机的向上方向:up direction
  3. 相机的思考
    1. 如果相机与物体一起运动,且互相之间没有相对运动,则最终成像是相同的
    2. 为了方便计算,默认将相机放在原点上,朝向-z方向,以Y为向上方向,其他物体按相机的变换做同等变换
  4. 如何将相机移动到原点,且保持朝向-z,y为上方向?
    1. 设相机位置为e,朝向向量为g,向上方向为t,且g,t为单位向量
    2. 做平移变换,这样相机坐标位于原点,(1, 0, 0, -xe, 0, 1, 0, -ye, 0, 0, 1, -ze, 0, 0, 0, 1)
    3. 将g旋转至-z方向,t旋转至y方向,gxt旋转至x方向
    4. 由于计算复杂,可以计算其逆变换,即x旋转至gxt,y旋转至t,z旋转至-g, (x(gxt), xt, x(-g), 0, y(gxt), yt, y(-g), 0, z(gxt), zt, (z-g), 0, 0, 0, 0, 1)
    5. 利用旋转矩阵特性,逆矩阵=转置矩阵,最终得到旋转矩阵,(x(gxt), y(gxt), z(gxt), 0, xt, yt, zt, 0, x(-g), y(-g), z(-g), 0, 0, 0, 0, 1)
    6. 视图矩阵 = 旋转矩阵 * 平移矩阵(这里是先平移,再旋转)
    7. 其他所有物体也按视图矩阵做变换

投影变换

  1. 本质:将3d物体转化为2d投影
  2. 分类:正交投影和透视投影
  3. 正交投影的变换矩阵
    1. 首先定义相机为一个立方体(left, right), (up, bottom), (far, near)
    2. 将该立方体中心平移至原点,(1, 0, 0, -(left + right)/2, 0, 1, 0, -(up+bottom)/2, 0, 0, 1, -(far+near)/2, 0, 0, 0, 1)
    3. 将该立方体缩放为[-1,1]的标准立方体,(2/(right-left), 0, 0, 0, 0, 2/(up-bottom), 0, 0, 0, 0, 2/(near-far), 0, 0, 0, 0, 1)
  4. 透视投影的变换矩阵
    1. 首先将透视矩阵远平面,压缩到跟近平面一样大,并且规定近平面和远平面的z轴值不变,且近平面不变,y1 = near / z * y, x1 = near / z * x
    2. (x, y, z, 1) => (near / z * x, near / z * y, unknown, 1) => (near * x, near * y, unknown, z)
    3. 变换矩阵为,(near, 0, 0, 0, 0, near, 0, 0, ?, ?, A, B, 0, 0, 1, 0)
    4. 近平面和远平面的z不变,取近平面任意点(x, y, near, 1),和远平面中心点(0, 0, far, 1),左乘变换矩阵,可得(near * x, near * y, near * A + B, near),(0, 0, far * A + B, far)
    5. 求解方程组,near * A + B = near * near, far * A + B = far * far,可得,A = near + far, B = - near * far
    6. 所以透视投影到正交投影的转换矩阵为,(near, 0, 0, 0, 0, near, 0, 0, 0, 0, near + far, -near*far, 0, 0, 1, 0)
    7. 最后透视投影矩阵 = 正交投影矩阵 * 转换矩阵