《3D图像算法从入门到进阶(包含C实现).docx》由会员分享,可在线阅读,更多相关《3D图像算法从入门到进阶(包含C实现).docx(24页珍藏版)》请在第壹文秘上搜索。
1、3D图象算法3D简介我们首先从坐标系统起先。你或许知道在2D里我们常常运用笛卡儿坐标系统在平面上来识别点。我们运用二维(X,Y):X表示水平轴坐标,Y表示纵轴坐标。在3维坐标系,我们增加了Z,一般用它来表示深度。所以为表示三维坐标系的一个点,我们用三个参数(X,Y,Z)这里有不同的笛卡儿三维系统可以运用。但是它们都是左手螺旋或右手螺旋的。右手螺旋是右手手指的卷曲方向指向Z轴正方向,而大拇指指向X轴正方向。左手螺旋是左手手指的卷曲方向指向Z轴负方向。事实上,我们可以在任何方向上旋转这些坐标系,而且它们仍旧保持本身的特性。在计算机图形学,常用坐标系为左手坐标系(手背向上),所以我们也运用它。:X正
2、轴朝右Y正轴向上Z正轴指向屏幕里矢量什么是矢量?几句话,它是坐标集合。首先我们从二维矢量起先,(X,Y):例如矢量P(4,5)(一般,我们用表示矢量)。我们认为矢量P代表点(4,5),它是从原点指向(4,5)的有方向和长度的箭头。我们谈论矢量的长度指从原点到该点的距离。二维距离计算公式是IPl=sqrt(x2+y2)这里有一个好玩的事实:在ID(点在单一的坐标轴上),平方根为它的肯定值。让我们探讨三维矢量:例如P(4,-5,9),它的长度为IPI=sqrt(x2+y-2+z2)它代表在笛卡儿3D空间的一个点。或从原点到该点的一个箭头代表该矢量。在有关操作一节里,我们探讨更多的学问。矩阵起先,我
3、们从简洁的起先:我们运用二维矩阵4乘4矩阵,为什么是4乘4?因为我们在二维坐标系里而且我们须要附加的行和列来完成计算工作(本质缘由:在计算机图形学里应用的图形变换,事实上是在仿射空间而不是向量空间中进行的)。在二维坐标系我们须要3乘3矩阵。着意味着我们在3D中有4个水平参数和4个垂直参数,一共16个。例如:4x4单位矩阵IlOOOIo100100io100oii因为任何其它矩阵与之相乘都不变更,所以称之为单位阵。又例如有矩阵如下:I10-72245IIsin(八)cos(八)3432I-3528176II45-993216有关矢量和矩阵的操作我们已经介绍了一些特别简洁的基本概念,那么上面的学问
4、与三维图形有什么关系呢?本节我们介绍3D变换的基本学问和其它的一些概念。它仍旧是数学学问。我们要探讨有关矢量和矩阵操作。让我们从两个矢量和起先:(xl,yl,zl)+(x2,y2,z2)=(xl+x2,yl+y2,zl+z2)儿何意义:等于两个矢量组成的平行四边形的长对角线的矢量两个矢量减法的几何意义:等于两个矢量组成的三角形的另一条边的矢量很简洁,现在把矢量乘于系数(数乘):k?(X,y,z)=(kx,ky,kz)几何意义:将矢量进行缩放点积如下表示:(点积是个标量)(xl,yl,zl)?(x2,y2,z2)=xlx2+yly2+zlz2事实上,两个矢量的点枳被它们的模的乘积除,等于两个矢量
5、夹角的余弦(两个矢量的模与其夹角的余弦之积称为两个矢量的数量积(或称内积、点积)。所以cos(VCW)=V?w/IVIIWI几何意义:两个矢量的点积衡量着两个向量的角度关系。在物理上的意义假如两个矢量分别代表力和位移,那么两个矢量的点积就是功。留意并不表示指数而是两个矢量的夹角。点积可以用来计算光线与平面的夹角,我们在计算阴影一节里会具体探讨。现在探讨叉乘:(xl,yl,zl)X(x2,y2,z2)=(ylz2-zly2,zlx2-xlz2,xly2-ylx2)几何意义:叉乘的结果是一个伪向量,但是他的模是以此二向量为相邻两边的平行四边形面积叉乘对于计算屏幕的法向量特别有用。OK,我们已经讲完
6、了矢量的基本概念。我们起先两个矩阵的和。它与矢量相加特别相像,这里就不探讨了。设I是矩阵的一行,J是矩阵的一列,(i,j)是矩阵的一个元素。我们探讨与3D变换有关的重要的矩阵操作原理。矩阵相乘的几何意义:把两次线性变换合成一次两个矩阵相乘,而且MXNNXM0例如:(矩阵乘法是有依次的)AB4x4矩阵相乘公式假如A=(aij)4x4,B=(bij)4x4,那么AXB=SaljbjlSaljbj2Saljbj3SSa2jbjlSa2jbj2Sa2jbj3SSa3jbjlSa3jbj2Sa3jbj3SSa4jbjlSa4jbj2Sa4jbj3Saljbj4Ia2jbj4Ia3jbj4Ia4jbj4I
7、其中j=l,2,3,4而且假如AxB=(cik)4x4那么我们可以在一行上写下:cik=S4,j=laijbjk(al,a2,a3)xB=(Sum(aibil)+b4,1,Sum(aibi2)+b4,2,Sum(aibi3)+b4,3)现在,我们可以试着把一些矩阵乘以单位矩阵来了解矩阵相乘的性质。我们把矩阵与矢量相乘结合在一起。下面有一个公式把3D矢量乘以一个4x4矩阵(得到另外一个三维矢量)假如B=(bij)4x4,那么:(al,a2,a3)XB=(Saibil+b4,1,Saibi2+b4,2,Saibi3b4,3)这就是矢量和矩阵操作公式。从这里起先,代码与数学之间的联系起先清晰。变换我
8、们已经见过象这样的公式:t(tx,ty):(X,y)=(X+tx,y+ty)这是在二维笛卡儿坐标系的平移等式。下面是缩放公式:s(k):(X,y)=(kx,ky)旋转等式:r(q):(X,y)=(Xcos(q)-ysin(q),Xsin(q)+ycos(q)以上都是二维公式,在三维里公式的形式仍旧很相近。平移公式:t(tx,ty,tz):(X,y,z)=(x+tx,y+ty,z+tz)缩放公式:s(k):(X,y,z)=(kx,ky,kz)旋转公式(围绕Z轴):r(q):(X,y,z)=(Xcos(q)-ysin(q),Xsin(q)+ycos(q),z)所以我们可以写出像在二维中同样的变换公
9、式。我们通过乘以变换矩阵而得到新的矢量,新矢量将指向变换点。下面是全部三维变换矩阵:平移(tx,ty,tz)的矩阵10000100100lOItxtytz1I缩放(sx,sy,SZ)的矩阵Isz000II0sy00II00SX0II0001I绕X轴旋转角q的矩阵I1000I0cos(q)sin(q)0I0-sin(q)cos(q)0I0001绕Y轴旋转角q的矩阵:Icos(q)0-sin(q)0I0100IIsin(q)0cos(q)0I0001绕Z轴旋转角q的矩阵:Icos(q)sin(q)00|I-sin(q)cos(q)00|I0010II0001I所以我们已经可以结束关于变换的部分.通
10、过这些矩阵我们可以对三维点进行任何变换.平面和法向量平面是平坦的,无限的,指向特定方向的表面可以定义平面如下:Ax+By+Cz+D=0其中A,B,C称为平面的法向量,D是平面到原点的距离。我们可以通过计算平面上的两个矢量的叉积得到平面的法向量。为得到这两个矢量,我们须要三个点。Pl,P2,P3逆时针排列(转入仿射空间了),可以矢量I=PI-P2和矢量2=P3-P2计算法向量为:法向量=矢量1X矢量2把D移到等式的右边得到:D=-(Ax+By+Cz)或D=-(A?l.x+B?2.y+C?3.z)或更简洁:D=-Normal?P1但是为计算A,B,C重量。可以简化操作按如下等式:A=yl(z2-z
11、3)+y2(z3-zl)+y3(zl-z2)B=Zl(x2-x3)+z2(x3-xl)+z3(xl-x2)C=xl(y2-y3)+x2(y3-yl)+x3(yl-y2)D=-xl(y2z3-y3z2)-x2(y3zl-ylz3)-x3(ylz2-y2zl)三维变换存储坐标实现矩阵系统实现三角法系统创建变换矩阵如何创建透视变换对象存储坐标首先可以编写星空模拟代码。那么我们基本的结构是什么样?每一个对象的描述是如何存储的?为解决这个问题,首先我们思索另一个问题:我们须要的是什么样的坐标系?最明显的答案是:屏幕坐标系:相对于显示器的原点的2D坐标系本地坐标系:相对于对象的原点的3D坐标系但是我们不要
12、遗忘变换中间用到的坐标系,例如:世界坐标系:相对于3D世界的原点三维坐标系对齐(视点)坐标系:世界坐标系的变换,视察者的位置在世界坐标系的原点。下面是坐标的基本结构:/二维坐标typedefstructshortx,y;_2D;三维坐标typedefstructfloatx,y,z;_3D;这里,我们定义了称为顶点的坐标结构。因为“顶点”一词指两个或两个以上菱形边的交点。我们的顶点可以简洁地认为是描述不同系统的矢量。不同的坐标系的坐标typedefstruct(_3D1.ocal;_3DWorld;_3DAligned;Vertex_t;实现矩阵系统我们须要存储我们的矩阵在4x4浮点数矩阵中。
13、所以当我们须要做变换是我们定义如下矩阵:floatmatrix44;然后我们定义一些函数来拷贝临时矩阵到全局矩阵:voidMAT_Copy(floatsource44,floatdest44)(inti,j;for(i=0;i4;i+)for(j=0;j4;j+)destij=sourceij;很简洁!现在我们来写两个矩阵相乘的函数。同时可以理解上面的一些有关矩阵相乘的公式代码如下:voidMATMuIt(floatmat144,floatmat244,floatdest44)(inti,j;for(i=0;i4;i+)for(j=0;jx=Source-x*mat00+Source-y*mat10+Source-z*mat20+mat30;Dest-y=Source-x*mat0l+Source-y*mat1l+Source-z*mat2l+mat31;Dest-z=Source-x*mat02+Source-y*mat12+Source-z*mat22+mat32;)/Source源矢量(坐标)/mat变换矩阵/Dest目标矩阵(坐标)我们已经得到了矩阵变换函数,不错吧!留意,这里的矩阵变换与我们学过的矩阵变换不同一般的,Y=TX,T为变换矩阵,这里为Y=XT,