图形学课程设计报告

时间:2024.4.13

可视化报告

一、  所选题目

长方体的光照效果可视化显示。

二、可视化简介

可视化(Visualization)是利用计算机图形学和图像处理技术,将数据转换成图形或图像在屏幕上显示出来,并进行交互处理的理论、方法和技术。它涉及到计算机图形学、图像处理、计算机视觉、计算机辅助设计等多个领域,成为研究数据表示、数据处理、决策分析等一系列问题的综合技术。目前正在飞速发展的虚拟现实技术也是以图形图像的可视化技术为依托的。

最近几年计算机图形学的发展使得三维表现技术得以形成,这些三维表现技术使我们能够再现三维世界中的物体,能够用三维形体来表示复杂的信息,这种技术就是可视化(Visualization)技术。可视化技术使人能够在三维图形世界中直接对具有形体的信息进行操作,和计算机直接交流。这种技术已经把人和机器的力量以一种直觉而自然的方式加以统一,这种革命性的变化无疑将极大地提高人们的工作效率。可视化技术赋予人们一种仿真的、三维的并且具有实时交互的能力,这样人们可以在三维图形世界中用以前不可想象的手段来获取信息或发挥自己创造性的思维。机械工程师可以从二维平面图中得以解放直接进入三维世界,从而很快得到自己设计的三维机械零件模型。医生可以从病人的三维扫描图象分析病人的病灶。军事指挥员可以面对用三维图形技术生成的战场地形,指挥具有真实感的三维飞机、军舰、坦克向目标开进并分析战斗方案的效果。

更令人惊奇的是目前正在发展的虚拟现实技术,人们对计算机可视化技术的研究已经历了一个很长的历程,而且形成了许多可视化工具,其中SGI公司推出的GL三维图形库表现突出,易于使用而且功能强大。利用GL开发出来的三维应用软件颇受许多专业技术人员的喜爱,这些三维应用软件已涉及建筑、产品设计、医学、地球科学、流体力学等领域。随着计算机技术的继续发展,GL已经进一步发展成为OpenGL,OpenGL已被认为是高性能图形和交互式视景处理的标准,包括ATT公司UNIX软件实验室、IBM公司、DEC公司、SUN公司、HP公司、Microsoft公司和SGI公司在内的几家在计算机市场占领导地位的大公司都采用了OpenGL图形标准。

值得一提的是,由于Microsoft公司在Windows NT中提供OpenGL图形标准,OpenGL将在微机中广泛应用,尤其是OpenGL三维图形加速卡和微机图形工作站的推出,人们可以在微机上实现三维图形应用,如CAD设计、仿真模拟、三维游戏等,从而更有机会、更方便地使用OpenGL及其应用软件来建立自己的三维图形世界。

三、题目要求

a)       题目要求

    长方体,建立一个点光源,采用环境光和点光源漫反射光的光照模型,应用FLAT明暗处理方法,显示平行投影后的长方体光照效果。

b)      任务分析

本题目主要包括五个任务,1)长方体表面模型的建立  2)长方体的可见面判断  3)可见面的背光性判断4)可见面光照计算5)可见面光照效果显示。

其中,任务1)中,定义三维齐次坐标结构和面的结构;定义顶点表和面表,对长方体绕X轴旋转和绕Y轴旋转。

任务2)中对每一个面计算其外法向量及可见性

任务3)中对每个可见面计算其光线向量,并判断其是否为背光面。

任务4)计算每个见光面的环境光和点光源的漫反射分量。

任务5)用该面的光强显示该可见面

四、数据可视化流程

五、算法流程图

六、核心算法描述

(1)判断长方体六个面的可见性

首先计算每个面的外法向量N,视线方向为预先给定的方向eye,两个向量进行点积即可判断可见性;若点积结果>0,即cos>0,则此面可见;

点积结果<0,即cos<0,则此面不可见;若点积结果=0,即cos=0,则外法向量与视线方向垂直,长方形退化为一条直线。

(2)判断长方体六个面的向光性

先取每个面的中心点(对角线的中点)与点光源做差,得到的方向为照射此面的光线方向,根据光线方向与外法向量的点积判断每个面的向光性;

若点积结果>=0,即cos>=0,则此面为向光面;点积结果<0,即cos<0,则此面为背光面;

(3)环境光与漫反射光的颜色分量的叠加

照射到每个面的光照强度根据cos的不同而不同,因此,在计算向光性的时候将cos的值计算出,并保存在数组中,然后根据公式

计算出每个面的总光照强度,同时也计算出RGB模型的三个颜色分量,以便图形的显示。

(4)平行投影与窗视变换

平行投影:将三维的图形平行投影到XOY平面上。

窗视变换:

假定把窗口内的一点变换为视区中的一点

根据公式

   和  

进行窗口—视区变换,图形在视区中显示

(5)图形的显示

调用BeginPath()和EndPath()函数标记填充路径,并调用FillPath()选用当前画刷分别填充向光面(因每个面选用的画刷的颜色分量不同,而分别显示每个面的光照效果);背光面不进行填充。

七、算法步骤:

① 定义结构和变量

       定义三维齐次坐标结构和面结构;定义凸多面体表面模型,顶点表为顶点结构数组,面表为面结构数组,定义光照颜色分量结构,定义环境光模型与漫反射模型;

      ② 变量初始化

       在视图类构造函数中给顶点表赋值;给面表赋值(注意顶点序列顺序);

      ③ 分别对凸多面体绕X轴旋转和绕Y轴旋转。

      ④ 设置环境光光强,反射系数,点光源光强,点光源漫反射系数

⑤ 计算各面的可见性

           由相邻两条边的叉积计算面的外法向量,由外法向量与视线方向的点积判断面的可见性,若该面可见,继续进行下面步骤,否则该面结束。

    ⑥ 计算每个面的中心点,即各顶点求平均;计算入射光方向,即点光源坐标-面的中心点;计算入射光线与外法向量的夹角,若大于等于90度,则点光源无法直接照射到该中心点,即该面的点光源漫反射分量为0;否则根据入射光线与法向量夹角计算该面的点光源漫反射分量;该面的光强为环境光强分量与点光源漫反射分量之和。

⑦ 对该面的四个顶点作投影平面为XOY平面的平行投影。

    ⑧ 对该面的四个顶点作窗口-视区变换。

⑨ 用该面的光强显示其投影后的多变形区域

八、程序代码:

(1)      定义的结构体

    //定义三维齐次坐标结构

typedef struct tagHOMOCOORD

{

         float x;

         float y;

         float z;

         float w;

}HOMOCOORD;

//定义面的结构

typedef struct tagPLANE

{

       int v0, v1, v2, v3;

       bool bvisible;

       bool HeadLight;

}PLANE;

//定义点的结构,需要浮点数的xy

typedef struct tagMYPOINT

{

       float x,y;

}MYPOINT;

//定义颜色分量结构,需要的浮点数red,green,blue

typedef struct tagCOLOR

{

       float red,green,blue;

}LCOLOR;

//定义环境光模型与漫反射模型,需要变量为光强和反射系数,I_a表示环境光的光强,I_p表示漫反射光的光强;K_a表示环境光的反射系数,K_d表示漫反射光的反射系数

typedef struct tagINTENSE

{

       float I_a,I_p;

       LCOLOR K_a,K_d,I;

}LINTENSE;

(2)      Draw3Dview的源代码

// Draw3DView.cpp : implementation of the CDraw3DView class

#include "stdafx.h"

#include "Draw3D.h"

#include "Draw3DDoc.h"

#include "Draw3DView.h"

#include "math.h"

#define ROUND(a) int(a+0.5)//四舍五入

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView

IMPLEMENT_DYNCREATE(CDraw3DView, CView)

BEGIN_MESSAGE_MAP(CDraw3DView, CView)

           //{{AFX_MSG_MAP(CDraw3DView)

              // NOTE - the ClassWizard will add and remove mapping macros here.

              //    DO NOT EDIT what you see in these blocks of generated code!

           //}}AFX_MSG_MAP

           // Standard printing commands

           ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)

           ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)

           ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView construction/destruction

CDraw3DView::CDraw3DView()

{

           // TODO: add construction code here

}

CDraw3DView::~CDraw3DView()

{

}

BOOL CDraw3DView::PreCreateWindow(CREATESTRUCT& cs)

{

           // TODO: Modify the Window class or styles here by modifying

           //  the CREATESTRUCT cs

           return CView::PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView drawing

void CDraw3DView::OnDraw(CDC* pDC)

{

           CDraw3DDoc* pDoc = GetDocument();

           ASSERT_VALID(pDoc);

           // TODO: add draw code for native data here

           DrawMy3DGraphics();  //绘图函数

}

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView printing

BOOL CDraw3DView::OnPreparePrinting(CPrintInfo* pInfo)

{

           // default preparation

           return DoPreparePrinting(pInfo);

}

void CDraw3DView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

           // TODO: add extra initialization before printing

}

void CDraw3DView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{

           // TODO: add cleanup after printing

}

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView diagnostics

#ifdef _DEBUG

void CDraw3DView::AssertValid() const

{

           CView::AssertValid();

}

void CDraw3DView::Dump(CDumpContext& dc) const

{

           CView::Dump(dc);

}

CDraw3DDoc* CDraw3DView::GetDocument() // non-debug version is inline

{

           ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDraw3DDoc)));

           return (CDraw3DDoc*)m_pDocument;

}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CDraw3DView message handlers

void CDraw3DView::DrawMy3DGraphics()

{

           int i;

           //形体定义

           ptn=8;

           pts=new HOMOCOORD[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=new PLANE[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=new MYPOINT[ptn];

           RotateX(30);   //X轴逆时针旋转30

      RotateY(30);   //Y轴逆时针旋转30

    //外法向量

//N为外法向量,eye为视线方向,light表示点光源位置;u1u2分别是中间量

           HOMOCOORD *N,eye,*u1,*u2,light;

//L_tensep为点光源强度,L_tense为镜面反射光照强度,ADD_tense为叠加后的光照强度

           LINTENSE *L_tensep,L_tense,*ADD_tense;

           L_tensep = new LINTENSE[fn];

           ADD_tense=new LINTENSE[fn];

           float cos_theta[6];

           //cos_theta为入射光线与外法向量的夹角

           N=new HOMOCOORD[fn];

           u1=new HOMOCOORD[fn];

           u2=new HOMOCOORD[fn];

           eye.x=0;

           eye.y=0;

           eye.z=1;

           light.x=1;

           light.y=1;

           light.z=100;

           //判断每个面的可见性,并标记

      for(i=0;i<fn;i++)

           {

               u1[i].x=pts[faces[i].v1].x-pts[faces[i].v0].x;

            u1[i].y=pts[faces[i].v1].y-pts[faces[i].v0].y;

               u1[i].z=pts[faces[i].v1].z-pts[faces[i].v0].z;

            u2[i].x=pts[faces[i].v2].x-pts[faces[i].v1].x;

               u2[i].y=pts[faces[i].v2].y-pts[faces[i].v1].y;

               u2[i].z=pts[faces[i].v2].z-pts[faces[i].v1].z;

                N[i].x=u1[i].y*u2[i].z-u2[i].y*u1[i].z;

               N[i].y=u1[i].z*u2[i].x-u1[i].x*u2[i].z;

               N[i].z=u1[i].x*u2[i].y-u1[i].y*u2[i].x;

               if(N[i].x*eye.x+N[i].y*eye.y+N[i].z*eye.z > 0)

                     faces[i].bvisible=1;

                else

                     faces[i].bvisible=0;

           }

           //判断每个面的向光性,见光面为1,背光面为0

            for(i=0;i<fn;i++)

           {

               u1[i].x=(pts[faces[i].v0].x+pts[faces[i].v2].x)/2;

               u1[i].y=(pts[faces[i].v0].y+pts[faces[i].v2].y)/2;

               u1[i].z=(pts[faces[i].v0].z+pts[faces[i].v2].z)/2;

               u2[i].x=light.x-u1[i].x;

               u2[i].y=light.y-u1[i].y;

               u2[i].z=light.z-u1[i].z;

               cos_theta[i]=(N[i].x*u2[i].x+N[i].y*u2[i].y+N[i].z*u2[i].z)/(sqrt(N[i].x*N[i].x+N[i].y*N[i].y+N[i].z*N[i].z)*sqrt(u2[i].x*u2[i].x+u2[i].y*u2[i].y+u2[i].z*u2[i].z));

//计算总的入射光强与外法向量的夹角的余弦值

               if(cos_theta[i] > 0)    //判断面的向光性

               {

                      faces[i].HeadLight=1;

                   L_tensep[i].I_p=1;

               }

               else

               {

                      faces[i].HeadLight=0;

                      L_tensep[i].I_p=0;

                      cos_theta[i]=0;

               }

           }

            //初始化已知数据,材质为金的环境光反射率和漫反射光反射率的RGB分量值

           L_tense.K_a.red=0.247; 

        L_tense.K_d.red=0.752;

        L_tense.K_a.blue=0.075;  

        L_tense.K_d.blue=0.226;

    L_tense.K_a.green=0.200;  

        L_tense.K_d.green=0.606;

      L_tense.I_a=1;  

           //计算叠加后的光照强度的RGB分量

           for(i=0;i<fn;i++)

           {

ADD_tense[i].I.red=L_tense.I_a*L_tense.K_a.red+L_tensep[i].I_p*L_tense.K_d.red*cos_theta[i];

              ADD_tense[i].I.red=ADD_tense[i].I.red>1?1:ADD_tense[i].I.red;

               ADD_tense[i].I.green=L_tense.I_a*L_tense.K_a.green+L_tensep[i].I_p*L_tense.K_d.green*cos_theta[i];

              ADD_tense[i].I.green=ADD_tense[i].I.green>1?1:ADD_tense[i].I.green;

               ADD_tense[i].I.blue=L_tense.I_a*L_tense.K_a.blue+L_tensep[i].I_p*L_tense.K_d.blue*cos_theta[i];

              ADD_tense[i].I.blue=ADD_tense[i].I.blue>1?1:ADD_tense[i].I.blue;

           }

   

           //平行投影变换

           for(i=0;i<ptn;i++)

           {

              pts2D[i].x=pts[i].x;

              pts2D[i].y=pts[i].y;

           }

           //窗口-视区变换实现过程

           float wxl=-3,wxr=3,wyb=-3,wyt=3;

           int vxl=0,vxr=500,vyb=0,vyt=400;

   // 窗口-视区变换

   float  a=(vxr-vxl)/(wxr-wxl);

   float  b=vxl-wxl*a;

   float  c=(vyt-vyb)/(wyt-wyb);

   float  d=vyb-wyb*c;

   for(i=0;i<ptn;i++)

   {

              pts2D[i].x=a*pts2D[i].x+b;

              pts2D[i].y=c*pts2D[i].y+d;

   }

           //图形显示

           CClientDC dc(this);

      CBrush NewBrush,*pOldBrush;

           for(i=0;i<fn;i++)

           {

              dc.BeginPath();

NewBrush.CreateSolidBrush(RGB(ROUND(ADD_tense[i].I.red*255),ROUND(ADD_tense[i].I.green*255),ROUND(ADD_tense[i].I.blue*255)));

        pOldBrush=dc.SelectObject(&NewBrush);

              PLANE f=faces[i];

              if(faces[i].HeadLight==1)

              {

              dc.MoveTo(pts2D[f.v0].x,pts2D[f.v0].y);

              dc.LineTo (pts2D[f.v1].x,pts2D[f.v1].y);

               dc.LineTo (pts2D[f.v2].x,pts2D[f.v2].y);

               dc.LineTo (pts2D[f.v3].x,pts2D[f.v3].y);

               dc.LineTo (pts2D[f.v0].x,pts2D[f.v0].y);

              }

              dc.EndPath();

        dc.FillPath();

           }

}

void CDraw3DView::RotateX(int angle)   //x轴逆时针旋转

{

           float a=angle*PI/180;

           for(int i=0;i<ptn;i++)

           {

              float y,z;

              y=pts[i].y; z=pts[i].z;

              pts[i].y=y*cos(a)-z*sin(a);

              pts[i].z=y*sin(a)+z*cos(a);

           }

}

void CDraw3DView::RotateY(int angle)  //y轴逆时针旋转

{

           float b=angle*PI/180;

           for(int i=0;i<ptn;i++)

           {

              float x,z;

              x=pts[i].x; z=pts[i].z;

              pts[i].x=x*cos(b)+z*sin(b);

              pts[i].z=-x*sin(b)+z*cos(b);

           }

}

九、程序运行结果截图:

长方体光照后的效果显示:

十、参考文献

    [1].孔令德著.计算机图形学基础教程 (第二版) [M].清华大学

          出版社.2013.03.

    [2].陈为张嵩等著.数据可视化的基本原理与方法[M].科学

          出版社.2013.06.

    [3].谭浩强.C++面向对象程序设计[M].北京:清华大学出版

          ,2006

    [4].孔令德,叶瑶,杨慧炯. C++程序设计案列精编[M].北京:

         中国铁道工业出版社,2004

更多相关推荐:
计算机图形学课程设计报告1

目录1课程设计目的12系统功能介绍13程序代码和分析24总结45参考文献46源程序41计算机图形学课程设计报告1课程设计目的本课程主要内容包括计算机图形学的研究内容发展与应用图形输入输出设备图形显示原理图形软件...

计算机图形学课程设计报告

图形学课程设计多边形剪裁和填充图形软件设计1一题目内容说明1交互式地实现多边形的裁剪和填充2功能要求1窗口功能设计2实现鼠标画多边形与数据存储功能4实现鼠标剪裁窗口选择功能5实现多边形裁剪和填充功能二总体设计本...

计算机图形学课程设计报告

课程设计报告题目旋转四面体摘要本文主要描述了计算机图形学中,运用C++和OpenGL来实现的绘制一个实体四面体。其中简单的用glutTimerFunc,glutSpecialFunc等函数实现了用光标键控制其旋…

《计算机图形学》课程设计论文(参考)

攀枝花学院学生课程设计论文题目图书馆图书管理系统学生姓名学号所在院系计算机学院专业计算机科学与技术班级20xx级1班指导教师罗学刚20xx年6月13日攀枝花学院本科学生课程设计任务书注任务书由指导教师填写课程设...

计算机图形学课程设计

计算机图形学课程设计摘要巩固和实践计算机图形学课程中的理论和算法学习表现计算机图形学算法的技巧培养认真学习积极探索的精神总体要求策划设计并实现一个能够充分表现某个图形学算法的关键词计算机算法类别专题技术来源1本...

《计算机图形学》课程设计报告

计算机图形学课程设计报告课题名称SolarSystem大阳系课题负责人名学号曾睿0643111150同组成员名单角色曾睿0643111150指导教师李征评阅成绩评阅意见提交报告时间20xx年12月17日课题名称...

计算机图形学课程设计报告要求及模板

计算机图形学课程设计报告学院计算机工程学院班级姓名学号成绩指导老师王丰汪志华评语20xx年1月15日一设计任务本次课程设计为学生提供了一个软件系统开发的独立实践机会根据计算机图形学课程所学的理论知识设计实现一个...

南邮计算机图形学实验报告(修正版)

实验报告12实验报告3三实验过程描述与结果分析实验代码includeltstdlibhgtincludeltGLgluthgtincludeltwindowshgtfloatratX60floatratY60f...

计算机图形学实验报告—正文

山东科技大学学生课程设计设计1环境设置实验环境microsoftvisualstudio20xx一实验目的1掌握图形驱动程序及图形模式的基本概念掌握图形初始化方法2掌握进行图形程序设计的基本方法3了解的图形功能...

计算机图形学实验报告-几何变换

班级R数学111大连交通大学姓名实验报告同组人课程名称计算机图形学成绩实验名称几何变换指导老师

精品图形学课程设计报告书-定

课程设计报告学生姓名学院班级题目刘名凤学号0809290102理学院信计081奥运五环指导教师常志文职称教授邓冠男职称助教20xx年5月31日目录目录2一选题背景111奥运五环设计的问题112奥运五环设计指导思...

计算机网络课程设计报告书

计算机网络实验报告题目某大学校园网规划与设计学院信息科学与工程学院专业班级计算机102班学号104162xx学生姓名xx成绩指导教师刘锁兰时间20xx年12月10日某大学校园网规划与设计某大学是一所极具现代意识...

计算机图形学课程设计报告(41篇)