5. 在OnDraw()中实现将立方体围绕z轴旋转15°,然后沿x,y轴各平移200,200,最后,做投影中心(视点)在(0,0,400),投影面在XOY平面的投影。 提示: sin(15°) = 0.25881904510252 cos(15°) = 0.96592582628907 绕z轴旋转的变换矩阵: 透视变换的矩阵: 参数θ和ψ的定义如下图所示,R是视点到世界坐标原点的距离,d是视点到投影面的距离 旋转矩阵的定义代码: 平移矩阵的定义代码: 投影矩阵的定义代码: 结果图
时间: 2024-03-05 09:48:41 浏览: 103
在OnDraw()函数中实现立方体绕z轴旋转15度,然后沿x轴和y轴分别平移200个单位,最后做透视投影。可以按照以下步骤进行实现:
1. 定义变换矩阵
首先,定义旋转、平移、透视投影变换的矩阵。根据题目给出的提示,可以使用以下代码定义旋转矩阵、平移矩阵和透视投影矩阵:
```c++
// 绕z轴旋转15度的变换矩阵
double rot_z[4][4] = {
{cos(15 * M_PI / 180), -sin(15 * M_PI / 180), 0, 0},
{sin(15 * M_PI / 180), cos(15 * M_PI / 180), 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 沿x轴平移200个单位的变换矩阵
double trans_x[4][4] = {
{1, 0, 0, 200},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 沿y轴平移200个单位的变换矩阵
double trans_y[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 200},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 透视投影的变换矩阵
double proj[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, -1.0 / 400},
{0, 0, 0, 0}
};
```
其中,rot_z表示绕z轴旋转15度的变换矩阵,trans_x和trans_y分别表示沿x轴和y轴平移200个单位的变换矩阵,proj表示透视投影的变换矩阵。
2. 进行变换
对立方体的每一个顶点进行变换,首先进行绕z轴旋转,然后进行x、y轴平移,最后进行透视投影。可以按照以下步骤进行实现:
```c++
// 定义变换后的顶点表
Vertex transformed_vertices[8];
// 对每个顶点进行变换
for (int i = 0; i < 8; i++) {
// 对顶点进行绕z轴旋转
double x1 = vertices[i].x * rot_z[0][0] + vertices[i].y * rot_z[0][1] + vertices[i].z * rot_z[0][2];
double y1 = vertices[i].x * rot_z[1][0] + vertices[i].y * rot_z[1][1] + vertices[i].z * rot_z[1][2];
double z1 = vertices[i].x * rot_z[2][0] + vertices[i].y * rot_z[2][1] + vertices[i].z * rot_z[2][2];
// 对顶点进行x轴平移
double x2 = x1 + trans_x[0][3];
double y2 = y1 + trans_x[1][3];
double z2 = z1 + trans_x[2][3];
// 对顶点进行y轴平移
x2 += trans_y[0][3];
y2 += trans_y[1][3];
z2 += trans_y[2][3];
// 对顶点进行透视投影
double x3 = proj[0][0] * x2 + proj[0][1] * y2 + proj[0][2] * z2 + proj[0][3];
double y3 = proj[1][0] * x2 + proj[1][1] * y2 + proj[1][2] * z2 + proj[1][3];
double z3 = proj[2][0] * x2 + proj[2][1] * y2 + proj[2][2] * z2 + proj[2][3];
double w = proj[3][0] * x2 + proj[3][1] * y2 + proj[3][2] * z2 + proj[3][3];
transformed_vertices[i].x = x3 / w;
transformed_vertices[i].y = y3 / w;
transformed_vertices[i].z = z3 / w;
}
```
在这段代码中,对每个顶点进行了绕z轴旋转、x、y轴平移和透视投影变换。变换后的顶点保存在transformed_vertices数组中。
3. 绘制立方体
根据变换后的顶点和面表,绘制变换后的立方体。具体实现可以参考以下代码:
```c++
// 绘制立方体
for (int i = 0; i < 6; i++) {
glBegin(GL_QUADS);
glColor3f(0.0f, 1.0f, 0.0f); // 设置颜色为绿色
glVertex3f(transformed_vertices[faces[i].v1].x, transformed_vertices[faces[i].v1].y, transformed_vertices[faces[i].v1].z);
glVertex3f(transformed_vertices[faces[i].v2].x, transformed_vertices[faces[i].v2].y, transformed_vertices[faces[i].v2].z);
glVertex3f(transformed_vertices[faces[i].v3].x, transformed_vertices[faces[i].v3].y, transformed_vertices[faces[i].v3].z);
glVertex3f(transformed_vertices[faces[i].v4].x, transformed_vertices[faces[i].v4].y, transformed_vertices[faces[i].v4].z);
glEnd();
}
```
4. 完整代码
以下是OnDraw()函数的完整代码:
```c++
void CMy3DProjectView::OnDraw(CDC* pDC)
{
CMy3DProjectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// 设置投影矩阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, 1.0, 0.1, 1000.0);
// 设置模型视图矩阵
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 400.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// 定义变换矩阵
// 绕z轴旋转15度的变换矩阵
double rot_z[4][4] = {
{cos(15 * M_PI / 180), -sin(15 * M_PI / 180), 0, 0},
{sin(15 * M_PI / 180), cos(15 * M_PI / 180), 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 沿x轴平移200个单位的变换矩阵
double trans_x[4][4] = {
{1, 0, 0, 200},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 沿y轴平移200个单位的变换矩阵
double trans_y[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 200},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
// 透视投影的变换矩阵
double proj[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0,
阅读全文