长方体体的光照效果计算机图形学课程设计 精品.docx
《长方体体的光照效果计算机图形学课程设计 精品.docx》由会员分享,可在线阅读,更多相关《长方体体的光照效果计算机图形学课程设计 精品.docx(23页珍藏版)》请在冰点文库上搜索。
长方体体的光照效果计算机图形学课程设计精品
西安科技大学
计算机图形学课程设计
题目:
长方体体的光照效果
专业班级:
信计1102班
小组成员:
陈维多1108060216
邹世林1108060224
左力1108060225
李优1108060229
日期:
2013年1月2日
目录
一课程设计题目…………………………………………………3
1.题目要求…………………………………………………3
2.任务………………………………………………………3
二任务分析算法介绍……………………………………………3
1.任务分析…………………………………………………3
2.算法介绍…………………………………………………4
三总体设计………………………………………………………5
1.定义三维齐次向量结构体………………………………5
2.定义三维齐次坐标结构…………………………………5
3.定义面的结构…………………………………………6
4.定义点的结构…………………………………………6
5.长方体顶点定义及初始化………………………………7
6.面表……………………………………………………7
7.定义点光源、视线方向、光照方向……………………8
8.各面可见性计算和判断…………………………………9
9.窗口-视区变换…………………………………………11
10.路径填充………………………………………………12
四流程图………………………………………………………13
五源程序………………………………………………………14
六程序运行效果图……………………………………………27
七总结…………………………………………………………28
参考文献…………………………………………………………29
一、课程设计题目
长方体体的光照效果
1.题目要求
对长方体,建立一个点光源,采用环境光和点光源漫反射光的光照模型,应用FLAT明暗处理方法,显示平行投影后的长方体光照效果。
2.任务
本题目主要包括五个任务,
1)长方体表面模型的建立
2)长方体的可见面判断
3)可见面的背光性判断
4)可见面光照计算
5)可见面光照效果显示
附加:
通过键盘上下左右按键对图形进行旋转
二、任务分析算法介绍
1.任务分析
任务1)中,定义三维齐次坐标结构和面的结构;定义顶点表和面表,对长方体绕X轴旋转和绕Y轴旋转。
任务2)中对每一个面计算其外法向量及可见性
任务3)中对每个可见面计算其光线向量,并判断其是否为背光面。
任务4)计算每个见光面的环境光和点光源的漫反射分量。
任务5)用该面的光强显示该可见面
附加:
人机交互
2.算法介绍
1)旋转变换
绕X轴旋转变换的坐标表示
绕Y轴旋转变换的坐标表示
2)平行投影
在XOY平面投影后坐标
3)环境光模型
物体没有受到光源的直射,但其表面仍有一定亮度,这是由于环境光的作用。
表示环境光反射强度
表示环境光反射率
表示环境光入射强度
4)漫反射光模型
漫反射光可认为是在点光源的照射下,光被物体表面吸收后,然后重新反射出来的光。
表示漫反射光强度
表示漫反射反射率
表示点光源入射强度大小
入射光与物体表面法矢量夹角
三、总体设计
1.定义三维齐次向量结构体
typedefstructVector3D
{
floatx;
floaty;
floatz;
intf;//f表示所在的平面的编号
}VECTOR;
2.定义三维齐次坐标结构
typedefstructtagHOMOCOORD
{
floatx;
floaty;
floatz;
floatw;
}HOMOCOORD;
3.定义面的结构
typedefstructtagPLANE
{
intv0,v1,v2,v3;
VECTORn;//外法向量
HOMOCOORDcenter;//中心点
floatId;//漫反射光强
intflag;//标识符
floatkd;//漫反射率
floatka;//环境光反射率
floatIe;//环境光反射光强
floatI;//光强
}PLANE;
4.定义点的结构
typedefstructtagMYPOINT
{
floatx,y;
}MYPOINT;
5.长方体顶点定义及初始化
pts=newHOMOCOORD[ptn];
pts[0].x=1;pts[0].y=2;pts[0].z=1;pts[0].w=1;
pts[1].x=-1;pts[1].y=2;pts[1].z=1;pts[1].w=1;
pts[2].x=-1;pts[2].y=-2;pts[2].z=1;pts[2].w=1;
pts[3].x=1;pts[3].y=-2;pts[3].z=1;pts[3].w=1;
pts[4].x=1;pts[4].y=2;pts[4].z=-1;pts[4].w=1;
pts[5].x=-1;pts[5].y=2;pts[5].z=-1;pts[5].w=1;
pts[6].x=-1;pts[6].y=-2;pts[6].z=-1;pts[6].w=1;
pts[7].x=1;pts[7].y=-2;pts[7].z=-1;pts[7].w=1;
6.面表
fn=6;
faces=newPLANE[fn];
faces[0].v0=0;faces[0].v1=1;faces[0].v2=2;faces[0].v3=3;
faces[1].v0=4;faces[1].v1=5;faces[1].v2=1;faces[1].v3=0;
faces[2].v0=5;faces[2].v1=6;faces[2].v2=2;faces[2].v3=1;
faces[3].v0=6;faces[3].v1=7;faces[3].v2=3;faces[3].v3=2;
faces[4].v0=7;faces[4].v1=4;faces[4].v2=0;faces[4].v3=3;
faces[5].v0=7;faces[5].v1=6;faces[5].v2=5;faces[5].v3=4;
7.定义点光源、视线方向、光照方向
1)点光源
illuminant.x=-100;
illuminant.y=-100;
illuminant.z=100;
Ia=0.5;//环境光入射强度
Ip=0.5;//漫反射入射光强度
2)视线方向
VECTOReye_vec;
eye_vec.x=0;
eye_vec.y=0;
eye_vec.z=-1;
3)定义光照方向
light_vec=newVECTOR[fn];
VECTORvector[6][2];
for(i=0;i<6;i++)
{
vector[i][0]=CalculateVector(pts[faces[i].v0],pts[faces[i].v1],i);
vector[i][1]=CalculateVector(pts[faces[i].v0],pts[faces[i].v2],i);
}
8.各面可见性计算和判断
1)计算各个面的外法向量
faces[0].n=VecCross(vector[0][0],vector[0][1]);
for(i=0;i<6;i++)
{
faces[i].n=VecCross(vector[i][0],vector[i][1]);
}
2)各个面的可见性判定
floatcos_angle;
for(i=0;i<6;i++)
{
cos_angle=(-1.0)*(InnerProduct(faces[i].n,eye_vec))/(GetModule(faces[i].n)*GetModule(eye_vec));
if(cos_angle>0)
faces[i].flag=VISIABLE;
else
faces[i].flag=UNVISIABLE;
}
3)计算各个面的中心点
for(i=0;i{
faces[i].center.x=(pts[faces[i].v0].x+pts[faces[i].v1].x+pts[faces[i].v2].x+pts[faces[i].v3].x)/4.0f;
faces[i].center.y=(pts[faces[i].v0].y+pts[faces[i].v1].y+pts[faces[i].v2].y+pts[faces[i].v3].y)/4.0f;
faces[i].center.z=(pts[faces[i].v0].z+pts[faces[i].v1].z+pts[faces[i].v2].z+pts[faces[i].v3].z)/4.0f;
faces[i].center.w=(pts[faces[i].v0].w+pts[faces[i].v1].w+pts[faces[i].v2].w+pts[faces[i].v3].w)/4.0f;
}
4)计算各个面的光照方向
for(i=0;i{
light_vec[i]=CalculateVector(illuminant,faces[i].center,EOF);
}
5)计算各个面的漫反射光强
for(i=0;i{
faces[i].Id=Ip*faces[i].kd*(-1)*(InnerProduct(faces[i].n,light_vec[i])/(GetModule(faces[i].n)*GetModule(light_vec[i])));
}
6)计算各个面环境光反射光强
for(i=0;i{
faces[i].Ie=faces[i].ka*Ia;
}
7)计算各个面光强(漫反射光强和环境反射光强之和)
for(i=0;i{
faces[i].I=faces[i].Id+faces[i].Ie;
}
//窗口-视区变换实现过程
floatwxl=-5,wxr=5,wyb=-5,wyt=5;
intvxl=0,vxr=800,vyb=0,vyt=600;
9.窗口-视区变换
inta=(int)((vxr-vxl)/(wxr-wxl));
intb=(int)(vxl-wxl*a);
intc=(int)((vyt-vyb)/(wyt-wyb));
intd=(int)(vyb-wyb*c);
for(i=0;i{
pts2D[i].x=a*pts[i].x+b;
pts2D[i].y=c*pts[i].y+d;
}
10.路径填充
CBrushBrush;Brush.CreateSolidBrush(RGB(faces[j].I*255,faces[j].I*255,faces[j].I*255+40));
pd.SelectObject(&Brush);
pd.BeginPath();
pd.MoveTo(p[0]);
for(inti=1;i<4;i++)
pd.LineTo(p[i]);
pd.LineTo(p[0]);
pd.EndPath();
pd.FillPath();
Brush.DeleteObject();
四、流程图
五、源程序
Draw3DView.h文件
//定义三维齐次向量结构体
typedefstructVector3D
{
floatx;
floaty;
floatz;
intf;//f表示所在的平面的编号
}VECTOR;
//定义三维齐次坐标结构
typedefstructtagHOMOCOORD
{
floatx;
floaty;
floatz;
floatw;
}HOMOCOORD;
//定义面的结构
typedefstructtagPLANE
{
intv0,v1,v2,v3;
VECTORn;//外法向量
HOMOCOORDcenter;//中心点
floatId;//漫反射光强
intflag;
floatkd;//漫反射率
floatka;//环境光反射率
floatIe;//环境光反射光强
floatI;//光强
}PLANE;
//定义点的结构,需要浮点数的x,y
typedefstructtagMYPOINT
{
floatx,y;
}MYPOINT;
public:
VECTORCalculateVector(HOMOCOORDstart,HOMOCOORDend,intface);//计算一个3维向量的函数,
//从start点指向end点的属于face面的向量
VECTORVecCross(VECTORvec1,VECTORvec2);//计算两个向量叉积,即外法向量
floatInnerProduct(VECTORvec1,VECTORvec2);//计算两个向量的内积
floatGetModule(VECTORvec);//计算向量的模
voidRotateY(intangle);//绕y轴逆时针旋转
voidRotateX(intangle);//绕x轴逆时针旋转
voidDrawMy3DGraphics();//绘制长方体
virtual~CDraw3DView();
protected:
HOMOCOORDilluminant;//定义光源坐标
floatIp;//定义光源光强
floatIa;//环境光光强
VECTOR*light_vec;//各个面的光照方向指针
HOMOCOORD*pts;//三维顶点指针
MYPOINT*pts2D;//自定义的二维浮点数结构,表示变换后的二维点
PLANE*faces;//长方体的面指针
intptn,fn;//顶点个数与面的个数
Draw3DView.cpp文件
intx_angle=0;
inty_angle=0;
voidCDraw3DView:
:
DrawMy3DGraphics()
{
inti;
//形体定义
ptn=8;
pts=newHOMOCOORD[ptn];
//设置长方体
pts[0].x=1;pts[0].y=2;pts[0].z=1;pts[0].w=1;
pts[1].x=-1;pts[1].y=2;pts[1].z=1;pts[1].w=1;
pts[2].x=-1;pts[2].y=-2;pts[2].z=1;pts[2].w=1;
pts[3].x=1;pts[3].y=-2;pts[3].z=1;pts[3].w=1;
pts[4].x=1;pts[4].y=2;pts[4].z=-1;pts[4].w=1;
pts[5].x=-1;pts[5].y=2;pts[5].z=-1;pts[5].w=1;
pts[6].x=-1;pts[6].y=-2;pts[6].z=-1;pts[6].w=1;
pts[7].x=1;pts[7].y=-2;pts[7].z=-1;pts[7].w=1;
///给定义面的指针分配内存;
fn=6;
faces=newPLANE[fn];
//设置立方体各面
faces[0].v0=0;faces[0].v1=1;faces[0].v2=2;faces[0].v3=3;
faces[1].v0=4;faces[1].v1=5;faces[1].v2=1;faces[1].v3=0;
faces[2].v0=5;faces[2].v1=6;faces[2].v2=2;faces[2].v3=1;
faces[3].v0=6;faces[3].v1=7;faces[3].v2=3;faces[3].v3=2;
faces[4].v0=7;faces[4].v1=4;faces[4].v2=0;faces[4].v3=3;
faces[5].v0=7;faces[5].v1=6;faces[5].v2=5;faces[5].v3=4;
pts2D=newMYPOINT[ptn];
for(i=0;i{
faces[i].ka=0.8;
faces[i].kd=0.8;
}
//定义点光源
illuminant.x=-100;
illuminant.y=-100;
illuminant.z=100;
Ia=0.5;
Ip=0.5;
//定义视线方向
VECTOReye_vec;
eye_vec.x=0;
eye_vec.y=0;
eye_vec.z=-1;
//定义光照方向
light_vec=newVECTOR[fn];
//旋转调用
RotateX(x_angle);
RotateY(y_angle);
//定义并计算各个面的两条相交的向量
VECTORvector[6][2];
for(i=0;i<6;i++)
{
vector[i][0]=CalculateVector(pts[faces[i].v0],pts[faces[i].v1],i);
vector[i][1]=CalculateVector(pts[faces[i].v0],pts[faces[i].v2],i);
}
//计算各个面的外法向量
faces[0].n=VecCross(vector[0][0],vector[0][1]);
for(i=0;i<6;i++)
{
faces[i].n=VecCross(vector[i][0],vector[i][1]);
}
//各个面的可见性判定
floatcos_angle;
for(i=0;i<6;i++)
{
cos_angle=(-1.0)*(InnerProduct(faces[i].n,eye_vec))/(GetModule(faces[i].n)*GetModule(eye_vec));
if(cos_angle>0)
faces[i].flag=VISIABLE;
else
faces[i].flag=UNVISIABLE;
}
//计算各个面的中心点
for(i=0;i{
faces[i].center.x=(pts[faces[i].v0].x+pts[faces[i].v1].x+pts[faces[i].v2].x+pts[faces[i].v3].x)/4.0f;
faces[i].center.y=(pts[faces[i].v0].y+pts[faces[i].v1].y+pts[faces[i].v2].y+pts[faces[i].v3].y)/4.0f;
faces[i].center.z=(pts[faces[i].v0].z+pts[faces[i].v1].z+pts[faces[i].v2].z+pts[faces[i].v3].z)/4.0f;
faces[i].center.w=(pts[faces[i].v0].w+pts[faces[i].v1].w+pts[faces[i].v2].w+pts[faces[i].v3].w)/4.0f;
}
//计算各个面的光照方向
for(i=0;i{
light_vec[i]=CalculateVector(illuminant,faces[i].center,EOF);
}
//计算各个面的漫反射光强
for(i=0;i{
faces[i].Id=Ip*faces[i].kd*(-1)*(InnerProduct(faces[i].n,light_vec[i])/(GetModule(faces[i].n)*GetModule(light_vec[i])));
}
//计算各个面环境光反射光强
for(i=0;i{
faces[i].Ie=faces[i].ka*Ia;
}
//计算各个面光强
for(i=0;i{
faces[i].I=faces[i].Id+faces[i].Ie;
}
//平行投影变换
for(i=0;i{
pts[i].x=pts[i].x;
pts[i].y=pts[i].y;
}
//窗口-视区变换
inta=(int)((vxr-vxl)/(wxr-wxl));
intb=(int)(vxl-wxl*a);
intc=(int)((vyt-vyb)/(wyt-wyb));
intd=(int)(vyb-wyb*c);
for(i=0;i{
pts2D[i].x=a*pts[i].x+b;
pts2D[i].y=c*pts[i].y+d;
}
///////////////////////////////////////////
//图形显示
CClientDCpd(this);
CPointp[4];
for(intj=0;j<6;j++)
{
if(faces[j].flag==VISIABLE)
{
p[0]=CPoint(p