GAMES-101-个人总结归纳-Transformation

(注:此文以个人知识框架为基础拓开,为方便后期回顾,在保留原课程内容框架的基础上,个别概念的介绍可能过于简单,感兴趣读者可到 GAMES 平台深入学习)

目录

2D Transform(rotation, scale, shear)

Homogeneous coordinates(齐次坐标)

Composite transform(变换组合)

3D transformations

正交矩阵

3D Rotations

欧拉角

Viewing transformation

 作业1:

题目简单介绍:

核心代码:

效果图


2D Transform(rotation, scale, shear)

  • Scale(缩放变换):

  • Reflection Matrix(反射变换):

  • Shear Matrix(切变):

Rotation Matrix(旋转):

注:T*A = A' => (T(-1))*A'  = A        对矩阵A作变换T,得到A';对应的还原为:对A'作 矩阵的逆。

Homogeneous coordinates(齐次坐标)

  • 引入:解决图像平移问题

  • 仿射变换:

    • 仿射=线性 + 平移

    • 将二维平面需要组合的平移操作,用一个3阶矩阵表示(问题:引入额外维度增加存储开销;已知仿射变换,尾阶默认(0,0,1),即 可忽略):

Composite transform(变换组合)

  • 矩阵乘法:右乘,满足结合律,分配律,不满足交换律。 
  • 顺序:1.先线性;2.再平移;

3D transformations

正交矩阵

  • R(T) = R(-1);矩阵的转置 等价于 矩阵的逆;

3D Rotations

  • xyz轴对应的旋转矩阵:

        

        

        

        注:关于Y轴不一样的解释:二维矩阵 {cos,-sin,sin,cos} {cos,sin,-sin,cos}互逆。(右手坐标系,右手螺旋定则(旋转角度不超过180°),cross 表示叉积);

        1.默认逆时针为正方向,看向对应轴负方向;

        2. x.cros(y) =z,旋转角x->y,90°;

            y.cross(z) = x,旋转角y->z,90°;

            x.cross(z) = y, 旋转角x->z,270°;>180°;所以正确的写法应该是 z.cross(x) = y;

            z->x,alpha°<=>x->z,-alpha°,所以变换矩阵就成了 {cos(-a),-sin(-a),sin(-a),cos(-a)},也就是{cos(a),sin(a),-sin(a),cos(a)};

        

欧拉角

  • yaw,roll, pitch(鸭肉-佩奇~~)

  • Rodrigues’ Rotation Formula(罗德里格旋转公式):欧拉角到矩阵的转换

        

 注:n:过远点的旋转轴;

Viewing transformation

  • View / Camera transformation

M(view) = T(view) * R(view);

T(view) 为相机坐标,直接通过齐次坐标写出:

 R(view) 为相机的视角变换,结果已知,可以通过先求逆变换,再对其做转置算出:

  • Projection transformation
  1. Orthographic projection(正交投影)
  •         成像空间为 长宽高均为1的 cube,坐标原点与 cube 中心重合;远近一致,先平移到原点,再做缩放:

        注:l(left),r(right),t(top),b(bottom),n(near),f(far);

  1. Perspective projection(透视投影)
  • 推到过程略,直接给出结论:
  • n(z轴近平面),f(z轴远平面)

        

 作业1:

题目简单介绍:

模拟一个基于CPU 的光栅化渲染器的简化版本,对于给定点的三角形,进行模型、视图、投影、视口等变换来将三角形显示在屏幕上(具体参考连接内pdf 说明文档)。

核心代码:

  •         1.绕z轴旋转:
/// <summary>
/// 绕z轴旋转
/// </summary>
/// <param name="rotation_angle">旋转角度</param>
/// <returns></returns>
Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    // TODO: Implement this function
    // Create the model matrix for rotating the triangle around the Z axis.
    // Then return it.

    float angle = rotation_angle;
    Eigen::Matrix4f rotation;
    angle = angle * MY_PI / 180.f;

    rotation << cos(angle), -sin(angle), 0, 0,
        sin(angle), cos(angle), 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1;

    return rotation;
}

        2.透视投影变换:

/// <summary>
/// 对三角形做透视投影变换,因右手坐标系,zFar<zNear
/// </summary>
/// <param name="eye_fov">垂直的可视角度</param>
/// <param name="aspect_ratio">显示宽高比</param>
/// <param name="zNear">z轴近平面坐标</param>
/// <param name="zFar">z轴远平面坐标</param>
/// <returns></returns>
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{
    // Students will implement this function

    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();

    // TODO: Implement this function
    // Create the projection matrix for the given parameters.
    // Then return it.

    float angle = eye_fov * MY_PI / 180.f;
    float top = -zNear * tan(angle / 2);//此处为负!!!!
    float bottom = -top;
    float right = top * aspect_ratio;
    float left = -right;

    Eigen::Matrix4f M_pers,M_origin,M_scaling;

    // 1.perspective transform
    M_pers << zNear, 0, 0, 0,
        0, zNear, 0, 0,
        0, 0, zNear + zFar, -zNear * zFar,
        0, 0, 1, 0;

    // orthographic projection
    // 2.move the centre point to (0,0,0)
    M_origin << 1, 0, 0, -(right + left) / 2,
        0, 1, 0, -(top + bottom) / 2,
        0, 0, 1, -(zFar + zNear) / 2,
        0, 0, 0, 1;

    // 3.scaling to unit space
    M_scaling << 2 / (right - left), 0, 0, 0,
        0, 2 / (top - bottom), 0, 0,
        0, 0, 2 / (zNear - zFar), 0,
        0, 0, 0, 1;
    
    projection = M_scaling * M_origin * M_pers;
    return projection;
}

3.绕过原点的任意轴旋转:

Eigen::Matrix4f get_rotation(Vector3f axis, float angle) {
    Eigen::Matrix4f M_axis;
    float nx = axis.x();
    float ny = axis.y();
    float nz = axis.z();

    angle = angle * MY_PI / 180.f;
    // 公式及推到参考:https://zhuanlan.zhihu.com/p/56587491
    M_axis << nx * nx * (1 - cos(angle)) + cos(angle), nx* ny* (1 - cos(angle)) + nz * sin(angle), nx* nz* (1 - cos(angle)) - ny * sin(angle), 0,
        nx* ny* (1 - cos(angle)) - nz * sin(angle), ny* ny* (1 - cos(angle)) + cos(angle), ny* nz* (1 - cos(angle)) + nx * sin(angle), 0,
        nx* nz* (1 - cos(angle)) + ny * sin(angle), ny* nz* (1 - cos(angle)) - nx * sin(angle), nz* nz* (1 - cos(angle)) + cos(angle),0,
        0, 0, 0, 1;
    Eigen::Matrix4f M_axis0 = M_axis.inverse();//求逆,本课程为右手坐标系,公式为左手坐标系,直接套用公式旋转会反向。
    return M_axis0;
}

效果图

(三角形坐标为:v0(2.0, 0.0,−2.0), v1(0.0, 2.0,−2.0), v2(−2.0, 0.0,−2.0),,观测点{0, 0, 5},观测方向:-z):

正常效果:

饶Z轴旋转10度:

 绕轴(0,0,-1)旋转10度:

 和图2刚好相反!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值