Open Cascade--坐标变换

OCCT V3d_View中的视图投影和方向由摄像机驱动。摄像机通过OpenGL计算并提供投影和视图方向矩阵进行渲染。因此后面的介绍都是基于OpenGL参考文献来进行说明(两者在矩阵坐标转换这块比较相似)

矩阵的几种线性变换:

几何实体的变换是通过矩阵来实现的,将各个定点以向量的形式表示,通过矩运算将顶点坐标进行转换。

位移:

位移(Translation)是在原始向量的基础上加上另外一个向量而获得在不同位置的新向量的过程,从而在位移向量的机车上移动了原始向量。

对于二维平面的平移操作:将对象从(x,y)位置移动到另一个位置(x',y'),其中Tx=x'-x,Ty=y'-y。因此平移变换用矩阵表示时,必须采用齐次坐标的形式

即P'=T*P(点乘)。

3D空间下平移矩阵如下所示:

齐次坐标:齐次坐标就是将一个原本n维的向量用一个n+1维向量来表示。例如,笛卡尔坐标上的点(x,y)的齐次坐标表示为(hx,hy,h)。原来笛卡尔坐标可透过将前面两个数值除以第三个数值取回,因此,与笛卡尔坐标不同,一个点可以有无线多个齐次坐标表示法。比如(8,4,2)、(4,2,1)表示的都是二维点(4,2)。

给出点齐次表达式[X,Y,H],就可以求得二维笛卡尔坐标,即

这个过程称为归一化处理。

在图形应用中涉及到几何变换,主要包括平移、缩放、旋转。以矩阵表达式来计算这些变换是,平移是矩阵相加,旋转和缩放则是矩阵相乘,综合起来可以表示为p*=m1*p+m2(m1旋转矩阵,m2平移矩阵,p为原向量,p*为变换后的向量)。引入齐次坐标的目的是合并矩阵运算中的乘法和加法,表示为p*=Mp的形式。

三维变换同上所述

缩放:

对一个向量进行缩放(Scaling)就是对向量的长度进行缩放,而保持它的方向不变。由于我们进行的是2维或3维操作,我们可以分别定义一个有2或3个缩放变量的向量,每个变量缩放一个轴(x、y或z)。

OpenGL中通常是在3D空间进行操作的,对于2D的情况,可以将z轴缩放1倍,这样z轴的值就不变了。同时其还可以进行均匀缩放与不均匀缩放。如,缩放向量v=(3,2)。我们可以把向量沿着x轴缩放0.5,使它的宽度缩小为原来的二分之一;我们将沿着y轴把向量的高度缩放为原来的两倍。

而在实际应用中,我们会构造一个变换矩阵来为我们提供缩放功能:

旋转:

旋转矩阵在3D空间中的每个轴都有不同的定义,在2D空间中可将其看作3D空间中的沿Z轴旋转

沿x轴旋转:

沿y轴旋转:

沿z轴旋转:

坐标系统:

OpenGL希望在所有顶点着色器运行之后,所有我们课件的定点都变味标准设备坐标(Normalized Device Coordinate,NDC)。将坐标转换为标准设备坐标,接着在转换为屏幕上的二维坐标或像素。

为了将一个坐标转换到另一个坐标系,我们需要用到几个转换矩阵,最重要的几个分别是模型(Model)、视图(View)、投影(projection)三个矩阵。首先,定点坐标开始于局部空间,称为局部坐标(Local Coordinate),让后经过世界坐标(World Coordinate)、观察坐标(View Coordinate)、剪裁坐标(Clip Coordinate)、最后以屏幕坐标(Screen Coordinate)结束。下图显示了整个流程以及各个转换过程做了什么:

  1. 局部坐标是对象相对于局部原点的坐标;也是对象开始的坐标。
  2. 将局部坐标转换为世界坐标,世界坐标是作为一个更大空间范围的坐标系统。这些坐标是相对于世界的原点的。
  3. 接下来将世界坐标转换为观察坐标,观察坐标是以摄像机或者观察者的角度观察的坐标。
  4. 在将坐标处理到观察空间之后,我们需要将其投影到剪裁坐标,剪裁坐标是处理-1.0到1.0范围内并判断哪些定点将会出现在屏幕上。
  5. 最后将剪裁坐标转换为屏幕坐标,这一过程称为视口变换(ViewPort Transform)。

局部空间:

局部空间是指对象所在的坐标空间,对象最开始所在的地方。局部坐标系(模型坐标系)仅对该物体适用,用来简化对物体各个部分坐标的描述。物体放到场景中是,各个部分经历的坐标变换相同,相对位置不变。

世界空间

如果我们想将我们所有的对象导入到程序当中,它们有可能会挤在世界的原点(0,0,0)上,然而这并不是我们先想要的 。我们想为每一个对象定义一个位置,从而是对象位于更大的世界当中。世界空间中的坐标就是指顶点相对于世界的坐标。物体变换到的最终空间就是世界坐标系。对象的坐标从局部坐标系转换到世界坐标系,经历的矩阵转换就是模型矩阵。

观察空间

观察空间经常被称作为OpenGL的摄像机(Camera),有时也称摄像机空间(Camera Space)或视觉空间(Eye Space)。观察空间就是将对象的世界空间的坐标转换为观察者视野前面的坐标。因此观察空间就是从摄像机的角度观察到的空间。通常由一系列的平移和选转组合来是特定的对象呗转换到摄像机面前。这些组合别存储在一个矩阵(观察矩阵)里,用来将世界坐标转换到观察坐标。

剪裁空间

为了将顶点的坐标从观察空间转换到剪裁空间,我们需要定义一个投影矩阵(Projection Matrix),它指定了坐标的范围,例如,每个维度都是从-1000到100.投影矩阵接着会将它指定的范围内的坐标转换到标准化设备坐标系中(-1.0,1.0)。所有在(-1.0,1.0)外的坐标都不会被绘制出来并且会被剪裁掉。在投影矩阵所指定的范围内,坐标(1250,400,750)将是不可见的,因为它的x轴坐标超出了范围,随后被转换为在标准设备中坐标值大于1.0的值,并且被剪裁掉。

由投影矩阵所创建的观察区域被称为投影平面,投影矩阵将观察坐标转换为裁剪坐标的过程采用两种不同的方式,正视投影(Orthographic)和透视投影(Perspective)

正视投影:

透视投影:

将上述步骤组合到一起,一个顶点的坐标将会根据以下过程被转换到裁剪坐标:

 

坐标变换:

模型变换:

模型变换的主要目的是通过变换使得对象能够按照需求,通过缩放、平移等操作放置到场景中合适的位置。通过模型变换后,对象放置在一个全局的世界坐标系中。

下图所示的茶壶模型变换描述了对像通过变换操作转移到世界坐标空间中:

视变换(View Transform):(可参考

视变换是为了方便观察场景中的对象而设立的,它将世界空间的对象转换到观察空间中(观察矩阵把所有的世界坐标变换到观察坐标)。观察空间的相机是一个假象的概念,是为了便于计算引入的。

定义一个摄像机,需要一个摄像机在世界空间中的位置、观察的方向、一个指向它的右轴的向量以及一个指向它上方的向量。

  1. 摄像机位置:摄像机位置简单来说就是世界空间中代表摄像机位置的向量。(摄像机往后移动就是往z轴正方向移动)
  2. 摄像机方向:指定位置后,下一个需要的向量是摄像机的方向,比如它指向那个方向。如:我们让摄像机指向场景的原点(0,0,0)。用摄像机位置减去原点向量的结果就是摄像机指向的向量。(方向向量(Direction Vector):注意图2,并不是最好的名字,因为它正好指向从它到目标向量的相反方向。)
  3. 右轴:代表摄像机空间的x轴的正方向。在获取右向量之前,定义一个上向量(ViewUp Vector)。然后将上向量和第二步得到的摄像机方向向量进行叉乘。两个向量叉乘的结果就是所求的指向x轴正方向的那个向量(如果交换两个向量的顺序就会得到指向x轴负方向的向量)。
  4. 上轴:在已有的x轴向量和z轴向量基础上,把右向量和方向向量(Direction Vector)进行叉乘。

投影变换:(投影矩阵和视口矩阵可参考

在经过视变换后,场景处于对于投影来说最友好的空间(视图空间),现在我们要做的就是把它投射到摄像机的虚拟屏幕上。在此之前,还需要进入另一个空间----投影空间,这个空间是一个长方体,其每个轴的维数都在-1到1之间,对于剪裁非常方便(-1:1范围之外的任何东西都在相机视图区域之外),并且但我们需要得到一个平面图像是,只需要删除z值就可以。

要从视图空间进入投影空间,我们需要另外一个矩阵,使其从视图到投影,这个矩阵的值取决于我们想要执行的投影类型:透视投影和正交投影

正视投影:我们必须定义摄像机能够看到的区域大小,通常是定义为x和y轴的宽度和高度值,以及z轴的远近值。如下图所示。

 

在设定这些值后,通过矩阵将项链从视图空间转为正交投影空间,并假定为右手坐标系

经过投影变换后,物体坐标变换到剪裁坐标系,经过OpenGL自动执行的透视除法后,变换到规范化设备坐标系(NDC)中。透视除法就是将剪裁坐标系中坐标都除以Wc成分的过程

视口变换

将投影变换的到的结果反映到指定屏幕上去(NDC坐标->屏幕坐标),有点类似于将底片冲洗到照片上,如果照片大小与底片不符,可将其进行缩放。

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值