计算机图形学实验几何物体的表示——三角网格的表示与显示

合集下载

三角网格的统一单分辨率与多分辨率表示方法

三角网格的统一单分辨率与多分辨率表示方法

三角网格的统一单分辨率与多分辨率表示方法
随着互联网的迅速发展,三角网格的技术越来越重要,成为互联网上常用的表示方法。

三角网格是一种用于处理模型表面形状的多面体网格,它由多边形的边缘和一种叫做“三角形”的基本多面体组成,是一种有效的表示和优化方式。

考虑到单分辨率与多分辨率的表示,三角网格的统一表示方法是迄今最有效的。

它提供了一种可扩展的表示方法,可以在不同分辨率下提供相同的精度。

根据不同的分辨率和参数,三角网格可以自适应模型表面的变化,提高计算效率。

在单分辨率的情况下,三角网格可以精确表示模型,从而提高产品的效果。

另一方面,多分辨率的表示方法也是相当重要的,它们可以帮助我们更好地描绘模型的表面。

多分辨率的表示方法可以提供更高的精度,并且可以更好地表达模型表面的细节。

在三角网格的多分辨率表示方法中,同一模型可以以不同分辨率格式表示,进一步提高了模型表面的精度。

在互联网上,三角网格的统一单分辨率与多分辨率表示方法可以大大提高模型质量,是一项非常重要的技术。

为了使互联网技术不断进步,三角网格技术需要得到大量的研究和发展,而中国的数字媒体技术又是向世界开放的,有着广阔的发展前景。

图形学中的光栅化与三角形填充算法

图形学中的光栅化与三角形填充算法

图形学中的光栅化与三角形填充算法光栅化和三角形填充算法是图形学中常用的技术,用于在计算机图形学中将2D或3D场景转换为最终在屏幕上呈现的图像。

本文将介绍光栅化和三角形填充算法的原理、应用和实现。

一、光栅化算法光栅化算法是指将连续的几何图形转化为离散的像素点的过程。

在计算机图形学中,屏幕被划分为一个个像素点的网格,每个像素点的颜色值由计算机确定。

通过光栅化算法,可以将几何图形的顶点信息转化为像素点的颜色值,从而实现图形的显示。

常用的光栅化算法有扫描线光栅化算法和射线光栅化算法。

1.扫描线光栅化算法扫描线光栅化算法逐行扫描图形,通过判断扫描线与几何图形的交点,确定像素点的颜色值。

这种算法适用于任意形状的几何图形。

在扫描线光栅化算法中,一般需要考虑图形的边界条件、插值计算和像素点的填充等问题。

2.射线光栅化算法射线光栅化算法通过从特定点向几何图形发射射线,并计算射线与几何图形的交点,确定像素点的颜色值。

这种算法适用于封闭的几何图形,如圆、椭圆等。

在射线光栅化算法中,常用的算法有中点画圆算法、Bresenham算法等。

光栅化算法广泛应用于计算机图形学中,用于生成点、线、多边形等几何图形的像素点的颜色值,从而实现图像的显示。

光栅化算法在计算机游戏、计算机辅助设计等领域有着广泛的应用。

二、三角形填充算法三角形填充算法是指将一个给定的三角形填充为实心或渐变颜色的过程。

在计算机图形学中,三角形是最基本的几何图形,通过三角形填充算法可以实现更复杂图形的显示和渲染。

常用的三角形填充算法有扫描线填充算法和边缘填充算法。

1.扫描线填充算法扫描线填充算法是通过遍历三角形内的每一行像素点,并判断像素点是否在三角形内部,从而确定像素点的颜色值。

该算法简单直观,但对于复杂的三角形可能效率较低。

2.边缘填充算法边缘填充算法是通过扫描三角形的边缘,并根据每个像素点的位置关系确定颜色值。

常用的边缘填充算法有中点边缘填充算法、贝塞尔曲线填充算法等。

计算机形学三维建模

计算机形学三维建模

计算机形学三维建模计算机形学三维建模是一种利用计算机技术对三维模型进行建立、编辑和渲染的过程。

它是计算机图形学的重要应用领域,广泛应用于电影特效、游戏设计、工业设计等领域。

本文将介绍计算机形学三维建模的基本概念、方法和应用。

一、概述计算机形学三维建模是指利用计算机生成三维物体模型的过程。

它通过数学和计算方法模拟现实物体的形状、结构和外观,并将其表示为计算机可识别的数据形式。

这种数据形式可以被进一步处理、编辑和渲染,用于实现各种视觉效果。

二、基本概念1. 顶点:三维建模中的基本元素,用于定义物体的位置和形状。

顶点通常由三个坐标值(x, y, z)表示。

2. 多边形:由多个顶点连接而成的平面图形,是构建三维物体的基本元素。

常见的多边形包括三角形、四边形等。

3. 网格:由多个相邻的多边形组成的三维物体表面。

网格可以用于表示复杂物体的形状和拓扑结构。

4. 法向量:用于定义物体表面的朝向和光照效果。

法向量垂直于表面,并指向物体外部。

5. 纹理映射:将二维图像映射到三维物体表面,用于增加物体的视觉效果和真实感。

三、建模方法计算机形学三维建模有多种方法和技术,常见的方法包括以下几种:1. 实体建模:基于物体的几何形状和结构进行建模。

可以通过对几何体进行布尔运算、体素细分等操作,实现复杂物体的建模。

2. 曲面建模:利用数学曲面方程对物体进行建模。

常见的曲面建模方法有贝塞尔曲线、B样条曲面等。

3. 多边形建模:将物体表示为由多边形组成的网格。

可以通过调整多边形的顶点和边界,实现物体形状的变化和编辑。

4. 数字雕刻:利用专业的数字雕刻软件对物体进行建模。

可以通过在三维空间中添加、删除和变形等操作,实现精细的物体建模。

四、应用领域计算机形学三维建模广泛应用于各个领域,主要包括以下几个方面:1. 电影特效:三维建模可以用于电影中的特殊效果制作,如人物角色、场景和特殊物体的建模。

2. 游戏设计:三维建模是游戏设计中必不可少的一部分。

三角形网格生成算法的研究与应用

三角形网格生成算法的研究与应用

三角形网格生成算法的研究与应用一、引言三角网格是计算机图形学领域中最常见的图形表示方式之一。

三角形网格生成算法的出现为图形学在各个领域的应用提供了强有力的支持,如计算机辅助设计、数字娱乐、医学图像处理等等。

然而目前三角形网格的生成算法依然存在许多难点,本文将针对这些难点进行研究和分析,探讨三角形网格生成算法的研究与应用。

二、先进的三角形网格生成算法三角形网格生成算法主要分为离散型和连续型两种。

离散型算法主要是针对离散数据点进行分析和处理,是传统算法的核心。

而连续型算法则主要考虑通过合理的数值方法对连续函数进行求解得到三角形网格。

2.1 离散型算法离散型算法主要方法包括 Delaunay 三角剖分、Voronoi 图、alpha 参数、最小生成树等等。

Delaunay 三角剖分是三角形网格分割中最常见的算法之一。

该算法的核心思想是保持尽量少的单纯形边长相交。

Voronoi 图是一种基于点的分割方法,可以将平面分割成一系列多边形。

Alpha 参数是控制 Delaunay 三角剖分质量的措施之一,通过调整 alpha 参数,可以在不同场景下获得合适的 Delaunay 三角剖分。

最小生成树算法则是对点集进行聚类的一种方法,通常用于优化 Delaunay三角剖分的质量。

2.2 连续型算法连续型算法主要包括渐近线、等值线、样条曲面拟合、卷积核方法等等。

渐近线的求解方法主要是对三角形网格表面进行采样后,通过函数空间中的拟合逼近来求解渐近线。

等值线方法则是在网格表面中寻找等值线,从而实现扫描三角形网格的目的。

样条曲面拟合是利用拟合优化方法,对离散的三角形网格点进行拟合,得到连续的三角形网格。

卷积核方法则通过对三角形表面求导以及在线性空间中构建卷积核,从而求得三角形网格表面的连续性信息。

三、三角形网格生成算法在计算机图形学领域的应用三角形网格生成算法在计算机图形学领域的应用十分广泛,主要包括三维重构、曲面拟合、形状建模、虚拟现实等等。

3D数字模型制作的算法研究

3D数字模型制作的算法研究

3D数字模型制作的算法研究一、引言3D数字模型制作是一门涉及数学、计算机图形学和计算机辅助设计等多个领域的学科,它在制造、建筑、电子游戏等诸多领域都有着广泛的应用。

如何高效、精确地制作出3D数字模型成为开展这一领域研究的关键问题,而算法的研究是实现这一目标必不可少的基础。

本文将从算法研究的角度探讨3D数字模型制作的相关问题。

二、体素表示法体素表示法(Voxel Representation)是表示3D数字模型的一种方法,它可以将模型划分成一系列小的块,每个块对应一个体素,然后对每个体素附加不同的属性值,如颜色、密度等信息。

该方法被广泛应用于医学成像、CAD等领域。

三、三角形网格表示法三角形网格表示法(Triangle Mesh Representation)是另外一种表示3D数字模型的方法,它通过将3D模型分解成一系列三角形网格来表示模型。

该方法能提高模型表现的真实感,但是模型的准确性不如体素表示法高。

四、3D扫描技术3D数字模型制作中最常用的技术之一是3D扫描,它通过激光器或相机等设备对物体进行扫描,然后将扫描数据转化为3D数字模型。

3D扫描技术可以分为接触式和非接触式两种方式。

其中接触式需要将物体与扫描设备接触,而非接触式则不需要接触。

五、曲面重构算法曲面重构算法是将三维散点云数据重构为曲面模型的一种算法,该算法主要通过插值、拟合等技术将散点云数据转化为曲面模型。

曲面重构算法被广泛应用于医学成像、地质勘探等领域。

六、贴图算法贴图算法是将二维图像贴到三维模型表面的一种算法,它可以为3D数字模型增添更加真实的纹理和颜色。

常用的贴图算法包括投影贴图、镜头贴图、UV贴图等。

七、射线跟踪算法射线跟踪算法是在3D数字模型中模拟真实世界光线传播的一种算法。

该算法可以模拟光线从光源射向物体表面,然后经过反射、折射等过程后到达观察者的过程。

射线跟踪算法被广泛用于计算机游戏、动画制作等领域。

八、小结3D数字模型制作是一个复杂的过程,需要借助各种算法的支持。

《计算机图形学》实验报告

《计算机图形学》实验报告

实验报告模板《计算机图形学》实验报告一、实验目的及要求1.实习三维图形的坐标系之间的变换;2.三维图形几何变换;3.掌握三维图形的坐标系之间的变换算法及三维图形几何变换的原理和实现;4.实现二维图形的基本变换(平移、旋转、缩放、错切、对称、复合等);5.实现三维图形的基本变换(平移、旋转、缩放、复合等);二、理论基础在齐次坐标理论下,二维图形几何变换矩阵可用下式表示:⎪⎪⎪⎭⎫⎝⎛===ifchebgdaTnkxx kk2,1,0,)(ϕ平移变换:[x* y* 1] =[x y 1] *0000001ts⎛⎫⎪⎪⎪⎝⎭=[t*x s*y 1]比例变换:[x* y* 1]=[x y 1] *1000101m n⎛⎫⎪⎪⎪⎝⎭=[m+x n+y 1]旋转变换:在平面上的二维图形饶原点逆时针旋转Ө角,变换矩阵为[x* y* 1]=[x y 1] *cos sin0sin cos0001θθθθ⎛⎫⎪- ⎪⎪⎝⎭= [x*cosө-y*sinө]复合变换:以上各种变换矩阵都是以原点为参照点,当以任意参照点进行变换的时候,我们就要用到复合变换矩阵。

三维变换类似于二维,在画图时,把三维坐标转换为二维即可。

三、算法设计与分析二维变换:#define dx 50#define dy 100void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+dx;a[1]=m[i][1]+dy;b[0]=m[i+1][0]+dx;b[1]=m[i+1][1]+dy;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define h 0.1745#include<math.h>void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*cos(h)-m[i][1]*sin(h);a[1]=m[i][1]*cos(h)+m[i][0]*sin(h);b[0]=m[i+1][0]*cos(h)-m[i+1][1]*sin(h);b[1]=m[i+1][1]*cos(h)+m[i+1][0]*sin(h);DDALine(a,b, RGB(0, 200, 255), pDC);}}#define k 2;#define f 2.5void CCGWithVCView::OnTransMove() //缩放{// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Scale Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*k;a[1]=m[i][1]*f;b[0]=m[i+1][0]*k;b[1]=m[i+1][1]*f;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define n 2#define d 0void CCGWithVCView::OnTransOther(){// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Other Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+n*m[i][1];a[1]=m[i][1]+d*m[i][0];b[0]=m[i+1][0]+n*m[i+1][1];b[1]=m[i+1][1]+d*m[i+1][0];DDALine(a,b, RGB(0, 200, 255), pDC);}}三维变换:#include<math.h>#define dx 100#define dy 100#define dz 0void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]+dy-p3d[i][0]+dx/sqrt(2);p2d[i][1]=p3d[i][2]+dz+p3d[i][0]+dx/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}#define k 0.1745void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]*cos(k)-p3d[i][2]*sin(k)-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]*cos(k)+p3d[i][1]*sin(k)+p3d[i][0]/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}四、程序调试及结果的分析二维:三维:五、实验心得及建议在实验过程中,尽管过程中任由许多不会的地方,而且有待于今后的提高和改进,但我加深了对书本上知识的理解与掌握,同时也学到了很多书本上没有东西,并积累了一些宝贵的经验,这对我以后的学习与工作是不无裨益的。

如何进行三角网的建立与处理

如何进行三角网的建立与处理

如何进行三角网的建立与处理在计算机科学领域中,三角网是一种用于连接数据点的网格结构。

它由许多三角形组成,每个三角形的三个顶点都是数据点。

三角网的建立和处理是许多计算机图形学和计算机视觉任务中的基础步骤。

本文将探讨如何进行三角网的建立与处理。

一、三角网的建立三角网的建立是通过一系列步骤来生成一个包含数据点的三角网格。

以下是一个简单的流程:1. 数据预处理:首先,需要根据实际应用场景,对数据点进行预处理。

这可能包括数据清洗、数据采样和数据变换等操作,以确保数据的质量和适用性。

2. 确定边界条件:在建立三角网之前,需要确定边界条件。

边界条件可以是已知的数据点或外部提供的信息。

边界条件的选择对于生成合理的三角网格非常重要。

3. 进行三角网格的初始化:在确定边界条件后,可以开始进行三角网格的初始化。

这可以通过将数据点放置在二维平面上,并根据某种规则(如Delaunay三角剖分算法)进行三角剖分来实现。

三角剖分算法是一种常用的方法,它能够确保所有的三角形都是“良好”的,即不会出现重叠或相交的情况。

4. 优化三角网:在初始化完成后,可能需要进行一些优化来改进生成的三角网。

例如,可以使用各种算法来优化三角网的质量和形状,以满足特定的需求。

常用的优化算法包括Laplacian平滑算法和拓扑优化算法等。

二、三角网的处理一旦三角网建立完成,就可以进行各种处理操作。

以下是一些常见的三角网处理技术:1. 网格编辑:三角网的处理通常涉及在网格上进行编辑和修改。

这可以通过添加、删除或移动数据点来实现。

网格编辑技术是计算机图形学和计算机视觉任务中的重要部分,可以用于模型编辑、形变和纹理映射等应用。

2. 网格分析:通过对三角网进行分析,可以获得有关数据点之间关系的更多信息。

例如,可以计算三角形的面积、周长和法向量等属性。

这些信息在许多应用中都是有用的,如物体表面重建、拓扑分析和形状匹配等。

3. 网格变形:通过对三角网进行变形操作,可以实现形状的变化和动画效果。

三维裁剪算法

三维裁剪算法

三维裁剪算法在计算机图形学中,三维裁剪算法是指将三维物体从视景体中裁剪出需要显示的部分,以提高图形渲染效率。

三维裁剪算法的基本思想是通过计算物体与视景体之间的关系,从而确定需要显示的部分并去掉不需要的部分。

三维物体的表示在三维计算机图形学中,通常使用多边形网格来表示三维物体。

多边形网格由许多平面上的三角形或四边形组成,每个多边形都有一组顶点坐标和法向量。

为了方便计算,通常将三维物体表示为一个顶点列表和一个面列表。

顶点列表包含所有顶点的坐标和法向量,面列表包含所有多边形的顶点索引和法向量。

视景体的表示视景体是指在三维计算机图形学中,用来界定场景中可见部分的区域。

视景体通常被定义为一个矩形长方体,其中心点为视点,长方体的六个面分别与屏幕平行。

视景体通常使用一个投影矩阵将三维物体投影到屏幕上。

三维裁剪的基本思想三维裁剪的基本思想是通过计算物体与视景体之间的关系,从而确定需要显示的部分并去掉不需要的部分。

三维裁剪可以分为平面裁剪和体裁剪两种。

平面裁剪平面裁剪是指通过计算多边形与平面之间的关系,从而确定需要显示的部分并去掉不需要的部分。

平面裁剪通常使用裁剪多边形的顶点,将其分割成多个小三角形,并将需要显示的三角形输出到屏幕上。

体裁剪体裁剪是指通过计算三维物体与视景体之间的关系,从而确定需要显示的部分并去掉不需要的部分。

体裁剪的基本思想是将三维物体与视景体分割成若干个小立方体,然后判断每个立方体是否在视景体内部。

如果一个立方体完全在视景体内部,则将其输出到屏幕上。

如果一个立方体完全在视景体外部,则将其丢弃。

如果一个立方体部分在视景体内部,则将其分割成多个小立方体,继续进行裁剪。

具体实现三维裁剪算法的具体实现方法有很多种,常用的有Sutherland-Hodgman算法、Cohen-Sutherland算法、Liang-Barsky算法等。

这些算法都能够高效地裁剪三维物体,并能够处理复杂的多边形和视景体。

总结三维裁剪算法是计算机图形学中的一项重要技术,可以提高图形渲染效率,使得三维物体能够更加逼真地显示在屏幕上。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验四几何物体的表示——三角网格的表示与显示1.实验目的●熟悉三角网格的表示●熟悉三角网格的显示●熟悉纹理的显示2.实验内容●设计三角网格的数据结构●解析Obj文件格式的三角网格●显示三角网格及纹理贴图3.实验指导存储三角网格数据的文件格式多种多样,常见的文件格式有:●Wavefront OBJ (*.0bj)●3D Max (*.max, *.3ds)●VRML (*.vrl)●Inventor (*.iv)●PLY (*.ply, *,ply2)本实验主要以OBJ文件为例,了解其数据格式,建立三角网格在内存中的数据结构,从而将文件中的数据读取到内存,并最终显示出来。

3.1OBJ文件格式OBJ文件是Alias|Wavefront公司为他的一套基于工作站的3D建模和动画软件“Advanced Visualizer”开发的一种标准3D模型文件格式,很适合用于3D软件模型之间的数据交换。

目前几乎所有知名的3D软件如3dsMax,LightWave,Maya都支持OBJ文件的读写。

OBJ文件是一种纯文本文件,可以直接用写字板打开进行查看和编辑修改。

这种文件以纯文本的形式存储了模型的顶点、法线和纹理坐标和材质使用信息。

OBJ的每一行,都有极其相似的格式,每行的格式如下:其中,前缀标识了这一行所存储的信息类型,参数则是具体的数据。

OBJ文件的前缀可以有:面的格式说明:每个三角面片的数据由f开头,后面跟组成该三角面片的各顶点的顶点坐标索引,纹理坐标索引,顶点法向索引,其格式为:f 顶点坐标索引/纹理坐标索引/顶点法向索引……其中纹理坐标索引和顶点法向索引可以为空,如果为空的索引位于末尾时,’/’也可以省略,例如:f 1 2 3这样的行表示以第1、2、3号顶点组成一个三角形,等同于1// 2// 3//。

f 1/3 2/5 3/4这样的行表示以第1、2、3号顶点组成一个三角形,其中第一个顶点的纹理坐标的索引值为3,第二个顶点的纹理坐标的索引值为5,第三个顶点的纹理坐标的索引值为4。

f 1/3/4 2/5/6 3/4/2这样的行表示以第1、2、3号顶点组成一个三角形,其中第一个顶点的纹理坐标的索引值为3,其法线的索引值是4;第二个顶点的纹理坐标的索引值为5,其法线的索引值是6;第三个顶点的纹理坐标的索引值为6,其法线的索引值是2。

f 1//4 2//6 3//2这样的行表示以第1、2、3号顶点组成一个三角形,且忽略纹理坐标。

其中第一个顶点的法线的索引值是4;第二个顶点的法线的索引值是6;第三个顶点的法线的索引值是2。

除此之外,以“#”开头的表示注释,以g开头的表示组的前缀。

但这些前缀并不影响模型的外观,因此我们可以忽略它们。

下面来看一个具体的实例,该文件是用3dsMax创建的一个长方体存储成OBJ 文件的结果:Obj格式对纹理的支持则是通过关键字mtllib指定的。

从上述例子可以看出,mtllib指定了对应于该obj文件的材质文件,材质文件的格式类似于obj的文件格式,也是由关键字前缀+对应的内容组成。

Ka,kd,ks分别指定了物体材质中环境光,漫反射光,镜面光的颜色,map_Kd 指定了纹理图像的路径,通过该纹理图像的路径,可以读取obj文件对应的纹理图像。

3.2 三角网格的数据结构三角网格的数据由几何和连接关系两部分组成,几何包括顶点的x ,y ,z 坐标及顶点的法向量等,连接关系即三角网格是如何连在一块的。

如图0.1所示。

3v 12v 4v 6v f 1f 2f 3f 4e 1e 2e 3e 4e 5e 6e 7e 8e 9(a ) (b )图0.1三角网格数据常用的三角网格数据结构包括: ● 顶点—边(Vertex-Edge ) ● 顶点—面(Vertex-Face )● 邻接矩阵(Adjacency matrix )和邻接表(Adjacency List ) ● 顶点—边—面(Vertex-Edge-Face ) ● 半边结构(Half Edge )在各种数据结构的表示方式中,几何的表示基本一致,可以用链表或者数组的方式加以存储,对于图0.1.a 中的网格,可表示为:区别的地方主要在于连接关系的存储,不同的存储方式决定了顶点、边、面的邻接关系的复杂度:顶点—边(Vertex-Edge)的数据结构只包含边的连接关系,对于图0.1.a中的网格,可表示为:顶点—面(Vertex-Face)的数据结构只包含面的连接关系,对于图0.1.a中的网格,可表示为:邻接矩阵(Adjacency matrix)的数据结构以矩阵的方式存储点与点之间的连接关系,对于图0.1.a中的网格,可表示为:顶点—边—面(Vertex-Edge-Face)的数据结构同时包含了边和面的连接关系,对于图0.1.a中的网格,可表示为:数据结构的选取,取决于对三角网格所进行的操作,如果需要频繁的对三角面片进行删除和插入的操作,如对三角网格进行简化时,则需要利用链表而非数组的方式来存储顶点的几何信息及连接关系,如果需要频繁的对顶点、边、面的邻接关系进行查询,则需要在避免过多冗余信息的同时,尽可能保存多的邻接关系,使得查询的复杂度为(1),如在顶点—边—面(Vertex-Edge-Face)的数据结构中对边的信息增加保存邻接三角形的信息,对顶点增加邻接边的信息。

对于图0.1.a中的网格,边的信息变成为:3.3三角网格的绘制在OpenGL中,任何复杂的几何物体最终都要描述成一个顶点的有序集合,即使是连续的曲线曲面,也需要首先对这些曲线曲面进行离散化,而后这些有序的顶点集合再组装成基本图元的集合。

OpenGL中,基本图元包括点、线段、三角形、多边形,而三角网格即为三角形这种基本图元的集合。

顶点表示:glVertex{2, 3, 4}{s, i, f, d}[v](坐标)此函数指定顶点的各个坐标分量。

基本几何图元基本几何图元的定义,以函数glBegin()开始,glEnd()结束,两函数之间的部分由组成该几何图元的顶点序列组成,如显示一个三角形,可以表示成:glBegin(GL_TRIANGLES);glVertex3f(x0, y0, z0);glVertex3f(x1, y1, z1);glVertex3f(x2, y2, z2);glEnd();glBegin(mode);此函数标志着描述一个几何图元的顶点序列的开始,图元的类型由参数mode指定,如表1所示,各个图元类型的效果如图0.2所示。

表1几何图元的名称和意义图0.2几何图元的类型glEnd()此函数标识着顶点列表的结束。

glBegin()和glEnd()函数对之间除了可指定顶点坐标的信息外,还可以指定法向、颜色、纹理坐标等信息,分别通过glNormal*(),glColor*(),glTexCoord()来实现。

以下代码将绘制一个红色和绿色三角形。

glBegin(GL_TRIANGLES);//red triangleglColor3f(1.0f, 0.0f, 0.0f, 1.0f);glVertex3f(x0, y0, z0);glVertex3f(x1, y1, z1);glVertex3f(x2, y2, z2);//green triangleglColor3f(0.0f, 1.0f, 0.0f, 1.0f);glVertex3f(x3, y3, z3);glVertex3f(x4, y4, z4);glVertex3f(x5, y5, z5);glEnd();三角网格中面的法向及顶点法向的计算每个面片处的法向可以通过两条边的叉乘得到,而顶点处的法向则可以取为相邻各三角面片法向的平均值,如错误!未找到引用源。

所示。

01 n = (v1 - v0) x (v2 - v0) n = ∑ni图0.3三角网格中免得法向及顶点法向的计算方法Obj文件中不但包含顶点几何坐标,还可以指定纹理数据,mtlib命令指定了材质属性的文件,材质属性文件中可以指定纹理图像所在的文件。

纹理的显示包括如下三个主要步骤:(1)生成纹理数据(2)将纹理数据载入纹理内存(3)将纹理数据映射到物体表面3.4生成纹理数据纹理数据可以由程序生成,也可以通过载入图像文件得到。

对于纹理映射而言,其目的一般是为了增强图形的真实感,因此通过拍摄实际场景得到相应的图片,然后再将图片映射到物体表面是使用较多的一种方法。

本实验也将采用载入图像文件的方法得到纹理数据。

3.4.1位图图像数据对于位图图像数据,可以通过MFC中的LoadImage()函数载入内存,而后通过CBitmap类中的GetBitmap()函数获取图像的具体信息,如图像的宽度,高度等信息,这些信息由BITMAP这个数据结构表示,如图0.4所示。

但值得注意的是,通过LoadImage()函数从文件载入的位图图像,GetBitmap()函数获取的图像信息中不包含位图的像素信息,bmBits为空,这需要通过CBitmap类中另一个函数GetBitmapBits()获得。

位图数据使用完后,还要通过CBitmap::DeleteObject()函数进行内存释放。

MFC中获取位图信息的数据流如图0.5所示。

图0.4 BITMAP的数据结构图0.5 MFC中获取位图信息的数据流表示HANDLE LoadImage(hInstance, lpszName, uType, cxDesired, cyDesired, fuLoad) 该函数用于从文件和资源中装载图标、光标、或位图。

hInstance:指定装载图像的模块特例,对于从文件载入图像可以设置为NULL。

lpszName:图像文件的路径或资源名称uType:指定被装载图像类型。

此参数可以为下列值,其含义如下:IMAGE_BITMAP:装载位图;IMAGE_CURSOR:装载光标;IMAGE_ICON:装载图标。

cxDesired,cyDesired:指定图标、光标的宽度和高度,以像素为单位。

若为载入位图,通常指定为0。

fuLoad:指定装载的类型,对于载入位图图像而言,该参数设定为LR_LOADFROMFILE。

通常,载入位图图像的调用方式为:HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, imagePath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)为获取位图的具体信息,需要将HBITAMP句柄转换为CBitmap类,这可以通过两种方式得到:(1)通过静态函数CBitmap::FromHandle()得到,即:CBitmap *pBitmap = CBitmap::FromHandle(hBitmap);这里需要注意的是,通过该函数得到位图变量pBitmap是一个指向临时CBitmap对象的指针,MFC框架会在空闲处理函数OnIdle()中自动释放这样的临时变量。

相关文档
最新文档