前言(Preface)
前段时间有些朋友在论坛里问到一些关于3D数学的知识,就想为大家写点这方面的文章。由于之前比较忙,又遇到过春节,所以最近才着笔写了这篇文章,希望大家喜欢。这些内容主要是一些理论知识,看上去难免有些枯燥,之后的文章我会加入一些实例进行讲解的。如果内容存在错误和不全,就请你来更正和添加了。
三维坐标系(3D Coordinate System)
三维坐标是把二维的平面坐标推广到三维空间中,在三维坐标中,点(x,y,z)的齐次坐标为(nx,ny,nz,n),其中n为任意不为0的数,规范化的齐次坐标为(x,y,z,1),与之相对应,三维变换的变换矩阵为4×4矩阵。
在三维空间中,我们通常使用右手坐标系(Right-Handed Coordinate System),因为它符合数学上的习惯,而在计算机图形学中,我们会使用左手坐标系(Left-Handed Coordinate System),因为它比较符合日常习惯。其实,我们可以任意的旋转这些坐标系,而图形仍然保持不变。常见的坐标系如下:
屏幕坐标系:相对于显示器的原点的2D坐标系
本地坐标系:相对于对象的原点的3D坐标系
世界坐标系:相对于3D世界的原点三维坐标系
对齐(视点)坐标系:世界坐标系的变换,观察者的位置在世界坐标系的原点。
点(Point)
点是在某一个坐标系中使用坐标值指定的位置。因此,点到坐标原点之间的距离与坐标系的选择有关。点P在坐标系A中的坐标为(0,0,0),而在坐标系B中的坐标则为(x,y,z)。
向量(Vector)
向量是指两点的差值,具有大小和方向,即给定两点,就能唯一确定一个向量,向量的大小和方向与坐标系的选择无关。向量V=(Vx,Vy,Vz)=P1P2=(x2-x1,y2-y1,z2-z1)其中,Vx,Vy和Vz分别为向量V在x,y和z轴上的投影,称为向量V的x分量(x component),y分量(y component)和z分量(z component)。该向量的大小为:
向量V与x,y和z轴形成的方向角(Direction Angle):α,β和γ,其中cosα,cosβ和cosγ称为方向余弦(Direction Cosine)。
向量加法:V1+V2=(V1x+V2x,V1y+V2y,V1z+V2z)
向量标量乘:aA=(aVx,aVy,aVz)
向量标量积:V1·V2= V1x+V2x,V1y+V2y,V1z+V2z
向量积(叉积):V1×V2=(V1yV2z-V1zV1y,V1zV2x-V1xV2z,V1xV2y-V1yV2z)
=Ux Uy Uz
V1x V1y V1z
V2x V2y V2z
注:其中Ux,Uy,Uz分别表示沿x轴,y轴和z轴的单位向量。在以后的编程中,我们经常会用到向量积。
矩阵(Matrix)
矩阵是由若干个数值构成的矩形阵列,这些数值通常为实数,称为矩阵的元素。如果一个矩阵的行和列数相同,我们则称该矩阵为方阵(Square Matrix),而只有一行或者一列的矩阵用常用向量表示,例如:[x,y,z]称为行向量(Row Vector),
x
y 则称为列向量(Colume Vector)。
z
矩阵加法:A11 A12 A13 B11 B12 B13 A11+ B11 A12+ B12 A13+ B13
A21 A22 A23 + B21 B22 B23 = A21+ B21 A22+ B22 A23+ B23
A31 A32 A33 B31 B32 B33 A31+ B31 A32+ B32 A33+ B33
矩阵标量乘: A11 A12 A13 nA11 nA12 nA13
nA21 A22 A23 = nA21 nA22 nA23
A31 A32 A33 nA31 nA32 nA33
矩阵的乘:
矩阵变换(Matrix Transform)
三维平移的矩阵表示为:
[x`,y`,z`,1]=[x,y,z,1] 1 0 0 0
0 1 0 0
0 0 1 0
tx ty tz 1
三维缩放的矩阵表示为:
[x`,y`,z`,1]=[x,y,z,1] sz 0 0 0
0 sy 0 0
0 0 sx 0
0 0 0 1
绕x轴旋转的矩阵表示为:
[x`,y`,z`,1]=[x,y,z,1] 1 0 0 0
0 cosα sinα 0
0 -sinα cosα 0
0 0 0 1
绕y轴旋转的矩阵表示为:
[x`,y`,z`,1]=[x,y,z,1] cosα 0 -sinα 0
0 1 0 0
sinα 0 cosα 0
0 0 0 1
绕z轴旋转的矩阵表示为:
[x`,y`,z`,1]=[x,y,z,1] cosα sinα 0 0
-sinα cosα 0 0
0 0 1 0
0 0 0 1
反射(Reflection)
反射变换也称为对称(Symmetric)变换或镜像(Mirror Image)变换,三维反射变换可以相对于反射轴(Reflection Axis)进行,也可以相对于反射平面进行。相对于反射轴的三维反射变换是通过将图形绕反射轴旋转180°来实现的。
相对于xy平面的反射变换矩阵为:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
相对于yz平面的反射变换矩阵为:
-1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
相对于zx平面的反射变换矩阵为:
1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1
错切(Shear)
错切变换会改变图形的形状。
相对于x轴的错切变换矩阵为:
1 0 0 0
shY 1 0 0
shz 0 1 0
0 0 0 1
相对于y轴的错切变换矩阵为:
1 shX 0 0
0 1 0 0
0 shz 1 0
0 0 0 1
相对于z轴的错切变换矩阵为:
1 0 shX 0
0 1 shY 0
0 0 1 0
0 0 0 1
从简单的平移、缩放和旋转等可以延伸到复合平移、复合缩放、复合旋转、固定点缩放等概念,这些就要靠读者自己查阅资料了,在这里我就不多讲了。
三维转换(3D Transform)
最常见的转换有以下三种类型:
1、世界坐标系转换:通过这种转换方式,可以改变3D物体的位置、大小、角度等等。就是改变3D世界中的物体位置相关的特性;
2、透视转换:透视转换决定了三维场景如何透视到二维平面上。包括观察三维世界摄象机镜头的观察范围等属性;
3、观察坐标系转换:这种转换方式决定了三维世界中观察者的位置,观察方向等属性。
投影变换(Projection Transformation)
投影变换就是将维数为n的点变换成维数小于n的点。我们会用到的就是将三维空间中的点变换成二维平面上的点。要对三维物体进行投影变换,首先要在三维空间中选择一个点,称为投影中心(Center of Projection);再定义一个不经过投影中心的平面,称为投影平面(Projection Plane);从投影中心向物体的没一点引射线,这些射线称为投影线(Projection Ray),投影线与投影平面的交点集合就称为三维物体在二维投影平面上的投影。
投影可以分为两大类,即透视投影(Perspective Projection)和平行投影(Parallel Projection);如果投影中心到投影平面的距离是有限的,那么投影线是从投影中心发出的无数条射线,这种投影称为透视投影;如果投影中心到投影平面的距离越来越远,那么投影线就越来越趋于平行,当投影中心到投影平面的距离为无穷远的时候,投影线为一组平行线,这种投影称为平行投影。
透视投影(Perspective Projection)
设投影中心为PC(XC,YC,ZC),投影平面为Z=ZP平面(ZP≠ZC),即投影平面平行与xy平面(垂直于z轴)并且不经过投影中心,三维空间中的点P(x,y,z)在投影平面上的透视投影为点PP(XP,YP,ZP)。
则透视投影矩阵为:
ZP-ZC 0 XC -XCZP
0 ZP-ZC YC -YCZP
0 0 ZP -ZCZP
0 0 1 -ZC
如果投影中心PC在坐标原点,投影平面仍然是Z=ZP平面,即XC=YC=ZC=0,那么透视投影矩阵变成:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 1/zP 0
如果投影中心PC在z轴上,投影平面是xy平面,即XC=YC=0,那么透视投影矩阵变成:
1 0 0 0
0 1 0 0
0 0 0 0
0 0 -1/zP 1
对于三维空间中任意一组平行线来说,如果它们平行于投影平面,那么它们的透视投影仍然保持平行;如果他们不平行于投影平面,那么它们的透视投影不再保持平行,并且会汇聚到一个点,该点称为灭点(Vanishing Point);平行于坐标轴的一组平行线形成的灭点称为主灭点(Principal Vanishing Point)或轴灭点(Axis Vanishing Point)。透视投影的主灭点的数目等于与投影平面相交的坐标轴的数目,而三维空间中的任意投影平面最少与一个坐标轴相交,最多与x,y,z三个坐标轴都相交,所以主灭点的数目最少为1个,最多为3个。根据主灭点的数目,我们可以将透视投影分为三类,即一点透视、二点透视和三点透视。
如果投影平面只与一个坐标轴相交,与另外两个坐标轴平行,那么透视投影只形成一个主灭点,称为一点透视。
如果投影平面与两个坐标轴相交,与剩下的一个坐标轴平行,那么透视投影形成两个主灭点,称为二点透视。二点透视比一点透视具有更强的真实感,被广泛地应用于建筑、工程、广告等领域。
平行投影(Parallel Projection)
根据投影方向的不同,我们可以把平行投影分为两类:如果投影方向与投影平面垂直,既投影方向与投影平面法向量的方向相同,那么这种投影称为正平行投影(Orthographic Parallel Projection),简称为正投影;如果投影方向与投影平面斜交,那么这种投影称为斜平行投影(Ohlique Parallel Projection),简称为斜投影。
1、 正投影
正投影经常用于产生物体的三视图。因为三视图能准确地反映物体的长度和角度。三视图是指投影方向分别取作x轴、y轴和z轴方向,投影平面分别垂直于x轴、y轴和z轴事的正投影,产生的视图分别成为前视图(Front View)、侧视图(Side View)和顶视图(Top View)。产生三视图的投影矩阵分别为:
Mfront= 0 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Mside= 1 0 0 0
0 0 0 0
0 0 1 0
0 0 0 1
Mtop= 1 0 0 0
0 1 0 0
0 0 0 0
0 0 0 1
当投影方向不取坐标轴方向,投影平面不垂直于坐标轴时,产生的正投影称为轴测正投影(Axonometric Orthographic Projection)。轴测正投影又分为正等测(Isimetric Projection)、正二测和正三测三种。当投影平面与三个坐标轴的交点到坐标原点的距离都相等时为正等测,也称为等轴测;当投影平面与两个坐标轴的交点到坐标原点的距离相等时为正二测;当投影平面与三个坐标轴的交点到坐标原点的距离都不相等时为正三测。
在这三种轴测正投影中,正等测应用最为广泛。由于正等测的投影平面与三个坐标轴的焦点到坐标原点的距离都相等,因此投影方向(即投影平面的法向量)与三个坐标轴的夹角也相等。
2、 斜投影
投影方向与投影平面斜交的平行投影称为斜投影。假设投影平面为Z=ZP平面,投影方向为(XD,YD,ZD)(ZD≠0),三维空间中的点P(x,y,z)在投影平面上的斜投影为点PP(xP,yP,zP)。则斜投影矩阵为:
ZD 0 -XD XDZP
0 ZD -YD YDZP
0 0 0 ZDZP
0 0 0 ZD
如果投影平面为z=0平面,即ZP=0,那么斜投影矩阵变成:
1 0 -XD/ZD 0
0 1 -YD/ZD 0
0 0 0 0
0 0 0 1
总结(Conclusion)
上面所提到的知识,都是我们平时编程时经常会用到的,可能还有些知识没提到,只好靠自己翻翻线形代数书了。如果对上面知识有什么不懂的和错误的,可以跟我讨论。如果你有基础知识,把这些理论用于实践应该是很轻松的事,如果你没有基础知识,也没什么大不了的,可以先看看关于OpenGL的书入门。这样上手会快一些。另外,上面的内存可能存在一些格式问题,请大家谅解。
(出处:http://www.knowsky.com)