GAMES101 作業1

作業目標是把三角形投影到屏幕上,並繞z軸旋轉(進階:繞任意軸旋轉)。

get_model_matrix

// TODO: Implement this function
// Create the model matrix for rotating the triangle around the Z axis.
// Then return it.
/**
 * @brief  控制model旋轉的矩陣
 * @note   
 * @param  rotation_angle: 繞z軸旋轉角度
 * @retval model矩陣
 */
Eigen::Matrix4f get_model_matrix(float rotation_angle)
{
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();
    float theta=rotation_angle/180*MY_PI;//弧度制轉角度制
    model<<
    cos(theta),-sin(theta),0.0,0.0,
    sin(theta),cos(theta),0.0,0.0,
    0.0,0.0,1.0,0.0,
    0.0,0.0,0.0,1.0;

    return model;
}

/**
 * @brief  繞旋轉軸dir旋轉rotation_angle度,dir過圓心
 * @note   直接套羅戈裏德斯公式
 * @param  dir: 過圓心的旋轉軸
 * @param  rotation_angle: 旋轉角度
 * @retval 
 *
*/
Eigen::Matrix4f get_model_matrix(Eigen::Vector3f dir,float rotation_angle)
{
    Eigen::Matrix4f model = Eigen::Matrix4f::Identity();

    float theta=rotation_angle/180*MY_PI;
    float nx=dir(0);
    float ny=dir(1);
    float nz=dir(2);

    Eigen::Matrix3f N = Eigen::Matrix3f::Identity();

    N<<
    0.0,-nz,ny,
    nz,0.0,-nx,
    -ny,nx,0.0;

    Eigen::Matrix3f matrix = Eigen::Matrix3f::Identity();
    matrix = cos(theta) * Eigen::Matrix3f::Identity() + (1-cos(theta)) * dir * dir.transpose() + sin(theta) * N;

    // 轉爲齊次座標
    model << 
    matrix(0,0), matrix(0,1), matrix(0,2), 0,
    matrix(1,0), matrix(1,1), matrix(1,2), 0,
    matrix(2,0), matrix(2,1), matrix(2,2), 0,
    0,0,0,1;

    return model;
}

get_projection_matrix

推導透視投影轉爲正方體過程中得用到齊次座標才能解出來(也就是必須按照閆佬講的那個過程),直接解的話解不出來。

// TODO: Implement this function
// Create the projection matrix for the given parameters.
// Then return it.
/**
 * @brief  將透視投影轉爲[-1,1]xyz範圍內的正方體(正交投影)
 * @note   
 * @param  eye_fov: 相機的fov
 * @param  aspect_ratio: 寬度和高度比
 * @param  zNear: 距離相機的Near平面距離
 * @param  zFar: 距離相機的Far平面距離
 * @retval 透視投影投影矩陣轉爲正方體(正交投影)的矩陣
 */
Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio,
                                      float zNear, float zFar)
{

    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
    // 視錐變爲長方體: near平面的座標不變,far平面的z座標不變,(x0,y0,z0)->(n/f*x0,n/f*y0,z0)
    Eigen::Matrix4f matrix1 = Eigen::Matrix4f::Identity();
    matrix1<<
    zNear,0.0,0.0,0.0,
    0.0,zNear,0.0,0.0,
    0.0,0.0,zFar+zNear,-zNear*zFar,
    0.0,0.0,1.0,0.0;

    // 變爲xyz[-1,1]範圍內的正方體
    // 先把長方體移動到原點
    Eigen::Matrix4f matrix2= Eigen::Matrix4f::Identity();
    matrix2<<
    1.0,0.0,0.0,0.0,
    0.0,1.0,0.0,0.0,
    0.0,0.0,1.0,(zNear+zFar)/2,
    0.0,0.0,0.0,1.0;

    // 縮放
    float theta=eye_fov/180*MY_PI;// fov的角度
    float h=2*tan(theta/2)*zNear;
    float w=h*aspect_ratio;
    Eigen::Matrix4f matrix3= Eigen::Matrix4f::Identity();
    matrix3<<
    2/h,0.0,0.0,0.0,
    0.0,2/w,0.0,0.0,
    0.0,0.0,2/(zFar-zNear),0.0,
    0.0,0.0,0.0,1.0;

    projection=matrix3*matrix2*matrix1;


    return projection;
}

倒三角形問題

一開始運行的時候,會得到一個倒三角(自己畫一下會發現應該是正的):

倒三角形問題我認爲是相機向上的定義沒寫清楚,應該在get_view_matrix中確定相機向上的向量


Eigen::Matrix4f get_view_matrix(Eigen::Vector3f eye_pos)
{
    Eigen::Matrix4f view = Eigen::Matrix4f::Identity();
    view(1,1)=-1.0;// 這裏確定相機向上的那個向量 不然投影出來的三角形是反的

    Eigen::Matrix4f translate;
    translate << 1, 0, 0, -eye_pos[0], 0, 1, 0, -eye_pos[1], 0, 0, 1,
        -eye_pos[2], 0, 0, 0, 1;

    view = translate * view;

    return view;
}

運行結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章