期末用2019.6(计算机图形学3,4次上机题的所有代码)
第4次上机
主要内容:二维投影,三维投影,图形放大缩小
void CTestView::ReadPoint()//点表
{
//顶点的三维坐标(x,y,z),立方体边长为2a
double a=150;
P[0].x = -a / 2; P[0].y = -a / 2; P[0].z = -a / 2;
P[1].x = +a / 2; P[1].y = -a / 2; P[1].z = -a / 2;
P[2].x = +a / 2; P[2].y = +a / 2; P[2].z = -a / 2;
P[3].x = -a / 2; P[3].y = +a / 2; P[3].z = -a / 2;
P[4].x = -a / 2; P[4].y = -a / 2; P[4].z = +a / 2;
P[5].x = +a / 2; P[5].y = -a / 2; P[5].z = +a / 2;
P[6].x = +a / 2; P[6].y =+a / 2; P[6].z = +a / 2;
P[7].x = -a / 2; P[7].y = +a / 2; P[7].z = +a / 2;
}
void CTestView::ReadFace()//面表
{
//面的顶点数和面的顶点索引
F[0].SetNum(4); F[0].vI[0] = 4; F[0].vI[1] = 5; F[0].vI[2] = 6; F[0].vI[3] = 7;
F[1].SetNum(4); F[1].vI[0] = 0; F[1].vI[1] = 3; F[1].vI[2] = 2; F[1].vI[3] = 1;
F[2].SetNum(4); F[2].vI[0] = 0; F[2].vI[1] = 4; F[2].vI[2] = 7; F[2].vI[3] = 3;
F[3].SetNum(4); F[3].vI[0] = 1; F[3].vI[1] = 2; F[3].vI[2] = 6; F[3].vI[3] = 5;
F[4].SetNum(4); F[4].vI[0] = 2; F[4].vI[1] = 3; F[4].vI[2] = 7; F[4].vI[3] = 6;
F[5].SetNum(4); F[5].vI[0] = 0; F[5].vI[1] = 1; F[5].vI[2] = 5; F[5].vI[3] = 4;
}
void CTestView::InitParameter()//透视变换参数初始化
{
k[1] = sin(PI*Theta / 180);
k[2] = sin(PI*Phi / 180);
k[3] = cos(PI*Theta / 180);
k[4] = cos(PI*Phi / 180);
k[5] = k[2] * k[3];
k[6] = k[2] * k[1];
k[7] = k[4] * k[3];
k[8] = k[4] * k[1];
}
void CTestView::PerProject(CP3 P)//透视变换
{
CP3 ViewP;
ViewP.x = P.x*k[3] - P.z*k[1];
ViewP.y = -P.x*k[8] + P.y*k[2] - P.z*k[7];
ViewP.z = -P.x*k[6] - P.y*k[4] - P.z*k[5] + R;
ScreenP.x = d * ViewP.x / ViewP.z;
ScreenP.y = d * ViewP.y / ViewP.z;
}
void CTestView::DrawObject(CDC* pDC)//绘制立方体线框
{
CP2 t;
CLine *line = new CLine;
for (int nFace = 0; nFace < 6; nFace++)
{
for (int nEdge = 0; nEdge < F[nFace].vN; nEdge++)
{
PerProject(P[F[nFace].vI[nEdge]]);
if (nEdge == 0)
{
line->MoveTo(pDC, ScreenP);
t = ScreenP;
}
else
{
line->LineTo(pDC, ScreenP);
}
}
line->LineTo(pDC, t);
}
delete line;
}
void CTestView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
R = R - 100;
InitParameter();//更新参数
Invalidate(FALSE);//重新绘制窗口
CView::OnRButtonDown(nFlags, point);//此行为最后一行
}
void CTestView::OnTwopoint()//工具条中二点透视按钮的响应函数
{
// TODO: 在此添加命令处理程序代码
KillTimer(1);
bPlay = FALSE;
Phi = 45; Theta = 0;
InitParameter();
Invalidate(FALSE);
}
void CTestView::OnThreepoint()//工具条中三点透视按钮的响应函数
{
// TODO: 在此添加命令处理程序代码
KillTimer(1);
bPlay = FALSE;
Phi = 45; Theta = 45;
InitParameter();
Invalidate(FALSE);
}
第三次上机
主要内容:Cohen-Sutherland直线段裁剪算法
void CTestView::Cohen()//Cohen-Sutherland算法,实现函数体
{
CP2 p;
EnCode(P[0]);
EnCode(P[1]);
while (P[0].rc != 0 || P[1].rc != 0)
{
if (0 != (P[0].rc&P[1].rc))
{
PtCount = 0;
return;
}
UINT RC = P[0].rc;
if (P[0].rc == 0) RC = P[1].rc;
if (RC & LEFT)
{
p.x = Wxl;
p.y = P[0].y + (P[1].y - P[0].y)*(p.x - P[0].x) / (P[1].x - P[0].x);
}
else if (RC & RIGHT)
{
p.x = Wxr;
p.y = P[0].y + (P[1].y - P[0].y)*(p.x - P[0].x) / (P[1].x - P[0].x);
}
else if (RC & BOTTOM)
{
p.y = Wyb;
p.x = P[0].x + (P[1].x - P[0].x)*(p.y - P[0].x) / (P[1].x - P[0].x);
}
else if (RC & TOP)
{
p.y = Wyt;
p.x = P[0].x + (P[1].x - P[0].x)*(p.y - P[0].y) / (P[1].y - P[0].y);
}
if (RC == P[0].rc)
{
EnCode(p);
P[0] = p;
}
else
{
EnCode(p);
P[1] = p;
}
}
}
void CTestView::EnCode(CP2 &pt)//端点编码函数, 实现函数体
{
pt.rc = 0;
if (pt.x < Wxl)
{
pt.rc = pt.rc | LEFT;
}
else if (pt.x > Wxr)
{
pt.rc = pt.rc | RIGHT;
}
if (pt.y < Wyb)
{
pt.rc = pt.rc | BOTTOM;
}
else if (pt.y > Wyt)
{
pt.rc = pt.rc | TOP;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现