ios 仿射变换(齐次坐标原理)三维透视投影

所谓齐次坐标就是将一个原本是n维的 向量用一个n+1维向量来表示。例如,二维点(x,y)的齐次坐标表示为(hx,hy,h)。由此可以看出,一个向量的齐次表示是不唯一的,齐次坐标的h取不同的值都表示的是同一个点,比如齐次坐标(8,4,2)、(4,2,1)表示的都是二维点(4,2)。
给出点的齐次表达式[X Y H],就可求得其二维笛卡尔坐标,即
[X Y H]→
= [x y 1], 这个过程称为正常化处理。
在几何意义上,相当于把发生在三维空间的变换限制在H=1的平面内。
那么引进齐次坐标有什么必要,它有什么优点呢?
许多图形应用涉及到 几何变换,主要包括平移、旋转、缩放。以矩阵表达式来计算这些变换时,平移是矩阵相加,旋转和缩放则是矩阵相乘,综合起来可以表示为p' = p *m1+ m2(m1旋转缩放矩阵, m2为平移矩阵, p为原向量 ,p'为变换后的向量)。引入齐次坐标的目的主要是合并矩阵运算中的乘法和加法,表示为p' = p*M的形式。即它提供了用矩阵运算把 二维、三维甚至 高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法。
其次,它可以表示无穷远的点。n+1维的齐次坐标中如果h=0,实际上就表示了n维空间的一个 无穷远点。对于齐次坐标(a,b,h),保持a,b不变,| V|=(x1*x1,y1*y1,z1*z1)^1/2的过程就表示了标准坐标系中的一个点沿直线 ax+by=0 逐渐走向无穷远处的过程。


"对于一个向量v以及基oabc,可以找到一组坐标(v1,v2,v3),使得v = v1 a + v2 b + v3 c (1)
而对于一个点p,则可以找到一组坐标(p1,p2,p3),使得 p – o = p1 a + p2 b + p3 c (2),
从上面对向量和点的表达,我们可以看出为了在坐标系中表示一个点(如p),我们把点的位置看作是对这个基的原点o所进行的一个位移,即一个向量——p – o(有的书中把这样的向量叫做位置向量——起始于坐标原点的特殊向量),我们在表达这个向量的同时用等价的方式表达出了点p:p = o + p1 a + p2 b + p3 c (3)
(1)(3)是坐标系下表达一个向量和点的不同表达方式。这里可以看出,虽然都是用代数分量的形式表达向量和点,但表达一个点比一个向量需要额外的信息。如果我写出一个代数分量表达(1, 4, 7),谁知道它是个向量还是个点!
我们现在把(1)(3)写成矩阵的形式:v = (v1 v2 v3 0) X (a b c o)
p = (p1 p2 p3 1) X (a b c o),这里(a,b,c,o)是坐标基矩阵,右边的列向量分别是向量v和点p在基下的坐标。这样,向量和点在同一个基下就有了不同的表达:3D向量的第4个代数分量是0,而3D点的第4个代数分量是1。像这种这种用4个代数分量表示3D几何概念的方式是一种齐次坐标表示。
这样,上面的(1, 4, 7)如果写成(1,4,7,0),它就是个向量;如果是(1,4,7,1),它就是个点。下面是如何在普通坐标(Ordinary Coordinate)和齐次坐标(Homogeneous Coordinate)之间进行转换:
(1)从普通坐标转换成齐次坐标时
如果(x,y,z)是个点,则变为(x,y,z,1);
如果(x,y,z)是个向量,则变为(x,y,z,0)
(2)从齐次坐标转换成普通坐标时 
如果是(x,y,z,1),则知道它是个点,变成(x,y,z);
如果是(x,y,z,0),则知道它是个向量,仍然变成(x,y,z)
以上是通过齐次坐标来区分向量和点的方式。从中可以思考得知,对于平移T、旋转R、缩放S这3个最常见的仿射变换,平移变换只对于点才有意义,因为普通向量没有位置概念,只有大小和方向.
而旋转和缩放对于向量和点都有意义,你可以用类似上面齐次表示来检测。从中可以看出,齐次坐标用于仿射变换非常方便。
此外,对于一个普通坐标的点P=(Px, Py, Pz),有对应的一族齐次坐标(wPx, wPy, wPz, w),其中w不等于零。比如,P(1, 4, 7)的齐次坐标有(1, 4, 7, 1)、(2, 8, 14, 2)、(-0.1, -0.4, -0.7, -0.1)等等。因此,如果把一个点从普通坐标变成齐次坐标,给x,y,z乘上同一个非零数w,然后增加第4个分量w;如果把一个齐次坐标转换成普通坐标,把前三个坐标同时除以第4个坐标,然后去掉第4个分量。
由于齐次坐标使用了4个分量来表达3D概念,使得平移变换可以使用矩阵进行,从而如F.S. Hill, JR所说,仿射(线性)变换的进行更加方便。由于图形硬件已经普遍地支持齐次坐标与矩阵乘法,因此更加促进了齐次坐标使用,使得它似乎成为图形学中的一个标准。
以上很好的阐释了齐次坐标的作用及运用齐次坐标的好处。其实在图形学的理论中,很多已经被封装的好的API也是很有研究的,要想成为一名专业的计算机图形学的学习者,除了知其然必须还得知其所以然。这样在遇到问题的时候才能迅速定位问题的根源,从而解决问题。"


(1)从普通坐标转换成齐次坐标时
如果(x,y,z)是个点,则变为(x,y,z,1);
如果(x,y,z)是个向量,则变为(x,y,z,0)
(2)从齐次坐标转换成普通坐标时 
如果是(x,y,z,1),则知道它是个点,变成(x,y,z);
如果是(x,y,z,0),则知道它是个向量,仍然变成(x,y,z)



深入研究iOS的三维透视投影

一.概述
在iOS中使用CATransform3D这个结构体来表示三维的齐次坐标变换矩阵. 齐次坐标是一种坐标的表示方法,n维空间的坐标需要用n+1个元素的坐标元组来表示,在Quartz 2D Transform中就有关于齐次坐标的应用,那边是关于二维空间的变换,其某点的齐次坐标的最后一个元素始终设置为1。使用齐次坐标而不是简单的数学坐标是为了方便图形进行仿射变换,仿射变换可以通过仿射变换矩阵来实现,3D的仿射变换可以实现诸如 平移(translation),旋转(rotation),缩放(scaling),切变(shear)等变换。如果不用齐次坐标那么进行坐标变换可能就涉及到两种运算了,加法(平移)和乘法(旋转,缩放),而使用齐次坐标以及齐次坐标变换矩阵后只需要矩阵乘法就可以完成一切了。上面的这些如果需要深入了解就需要去学习一下图形变换的相关知识,自己对矩阵的乘法进行演算。
iOS中的CALayer的3D本质上并不能算真正的3D(其视点即观察点或者所谓的照相机的位置是无法变换的),而只是3D在二维平面上的投影,投影平面就是手机屏幕也就是xy轴组成的平面(注意iOS中为左手坐标系),那么视点的位置是如何确定的呢?可以通过CATransform3D中的m34来间接指定, m34 = -1/z,其中z为观察点在z轴上的值,而Layer的z轴的位置则是通过anchorPoint来指定的,所谓的anchorPoint(锚点)就是在变换中保持不变的点,也就是某个Layer在变换中的原点,xyz三轴相交于此点。在iOS中,Layer的anchorPoint使用unit coordinate space来描述,unit coordinate space无需指定具体真实的坐标点而是使用layer bounds中的相对位置,下图展示了一个Layer中的几个特殊的锚点,

m34 = -1/z中,当z为正的时候,是我们人眼观察现实世界的效果,即在投影平面上表现出近大远小的效果,z越靠近原点则这种效果越明显,越远离原点则越来越不明显,当z为正无穷大的时候,则失去了近大远小的效果,此时投影线垂直于投影平面,也就是视点在无穷远处,CATransform3D中m34的默认值为0,即视点在无穷远处.
还有一个需要说明一下的就是齐次坐标到数学坐标的转换 通用的齐次坐标为 (a, b, c, h),其转换成数学坐标则为 (a/h, b/h, c/h).
二.代数解释
假设一个Layer anchorPoint为默认的 (0.5, 0.5 ), 其三维空间中一个A点 (6, 0, 0),m34 = -1/1000.0, 则此点往z轴负方向移动10个单位之后,则在投影平面上看到的点的坐标是多少呢?
A点使用齐次坐标表示为 (6, 0, 0, 1)
QuartzCore框架为我们提供了函数来算出所需要的矩阵,
    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = -1/1000.0;
    transform = CATransform3DTranslate(transform, 0, 0, -10);
计算出来的矩阵为

{ 1,    0,    0,     0;  
  0,    1,    0,     0;  
  0,    0,    1,     -0.001;  
  0,    0,  -10,    1.01;      
}  
其实上面的变换矩阵本质上是两个矩阵相乘得到的 变换矩阵 * 投影矩阵 变换矩阵为
{1,    0,    0,    0;  
0,    1,    0,    0;  
0,    0,    1,    0;  
0,    0,   -10,  1;      
}    
投影矩阵为

{1,    0,    0,    0;  
0,    1,    0,    0;  
0,    0,    1, -0.001;  
0,    0,    0,    1;  
}    
上面的两个矩阵相乘则会得到最终的变换矩阵(如果忘记矩阵乘法的可以去看下线性代数复习下),所以一个矩阵就可以完成变换和投影。
将A点坐标乘上最终的变换矩阵,则得到 {6, 0 , -10, 1.01}, 转换成数学坐标点为 {6/1.01, 0, 10/1.01},则可以知道其在投影平面上的投影点为 {6/1.01, 0, 0} 也就是我们看到的变换后的点。其比之前较靠近原点。越往z轴负方向移动,则在投影平面上越靠近原点。
三.几何解释
将上面的例子使用几何的方式来进行解释分析,当我们沿着y轴的正方向向下看时候,可以得到如下的景象

虚线为投影线,其和x轴的交点即为A点的投影点。 由相似三角形的定理我们很容易算出投影的点,
1000/(1000 + 10) = x/6,则x = 6*1000/1010 = 6/1.01



        首先想像有个绝对不变的坐标系(0,0),记为W,然后以W为参照,建立两个坐标系O1和O2, O1的原点在W的(1,1)处,O2的原点在W的(2,2)处。那么W中的一个点P(x,y)在O1中将变为P(x-1,y-1),在O2中将是P(x-2, y-2),这样同一个点P在不同的坐标系下就具有了不同的表示。这会产生一个问题:显然,P点在二维空间的位置是唯一的,是与坐标系无关的,而不同坐标系下的表示看上去体现不了这种无关性。

        我们使用的是坐标系这样一个概念,坐标系忽略了坐标原点所具有的重要意义:正是原点标示了该坐标系处于哪个参照位置。如果用矩阵来表示一个二维坐标系,将会是如下形式:
|1 0|

|0 1|,其中(1 0)T表示一个基矢量,(0 1)T表示另一个基矢量,它们互相垂直,因此能利用它们标记整个二维空间。
(x,y)*|1 0| = (x,y)

         |0 1|

这就是二维坐标的实际意义。

现在考虑将坐标原点(a,b)也引入到这个矩阵表示中来:
|1 0 |
|0 1 |
|a b |
我们用这个矩阵可以表示二维空间中任意位置的一个坐标系,当然,这个坐标系的基矢量可以不为(0 1)T和(1 0)T,为了和坐标系区分,我们称这种新表示为标架表示。
好,问题来了,如果我们仍然用(x y)来表示点P,那么根据矩阵的乘法规则,我们无法完成其乘法:mx N 的矩阵只能和 N xk的矩阵相乘。解决的办法就是: 给P点添一个尾巴,这个尾巴通常为1:P(x y 1),这就是P的齐次坐标,利用新的齐次坐标和矩阵相乘得到的结果为:(x+a, y+b),这样同一个点在不同标架下的不同表示最终会得到同一个计算结果,它反映了这样一个事实:同一个点在不同标架下的不同表示其实是等价的,这一点恰恰是使用坐标系无法体现出来的。
显然上面那个 3x2的矩阵和P的齐次表示相乘得到的不是齐次坐标,所以应该将它扩充成3x3的方阵:
|1 0 0|
|0 1 0|
|a b 1|

--------------------------------------------------------------------------------------------------------------

所谓齐次坐标就是将一个原本是n维的向量用一个n+1维向量来表示。


在空间直角坐标系中,任意一点可用一个三维坐标矩阵[x y z]表示。如果将该点用一个四维坐标的矩阵[Hx Hy Hz H]表示时,则称为齐次坐标表示方法。在齐次坐标中,最后一维坐标H称为比例因子。


齐次点具有下列几个性质:
  1)如果实数a非零,则(x, y, x, w)和(ax, ay, az, aw)表示同一个点,类似于x/y = (ax)/( ay)。
  2)三维空间点(x, y, z)的齐次点坐标为(x, y, z, 1.0),二维平面点(x,y)的齐次坐标为(x, y, 0.0, 1.0)。
  3)当w不为零时,齐次点坐标(x, y, z, w)即三维空间点坐标(x/w, y/w, z/w);当w为零时,齐次点(x, y, z, 0.0)表示此点位于某方向的无穷远处。


那么引进齐次坐标有什么必要,它有什么优点呢?
      1.它提供了用矩阵运算把二维、三维甚至高维空间中的一个点集从一个坐标系变换到另一个坐标系的有效方法。
      2.它可以表示无穷远的点。n+1维的齐次坐标中如果h=0,实际上就表示了n维空间的一个无穷远点。对于齐次坐标[a,b,h],保持a,b不变,    点沿直线 ax+by=0 逐渐走向无穷远处的过程。
--------------------------------------------------------------------------------------------------------------

注:本文转至    http://houdinime.blog.163.com/blog/static/112019079200921324514322/


为什么需要齐次坐标?  

      4D向量是由3D坐标(x,y,z)和齐次坐标w组成,写作(x,y,z,w)。

在3D世界中为什么需要3D的齐次坐标呢?简单地说明一下,在一维空间中的一条线段上取一点x,然后我们想转移x的位置,那我们应该是x'=x+k,但我们能使用一维的矩阵来表示这变换吗?不能,因为此时一维的矩阵只能让x点伸缩。但如果变成了一维的齐次空间[k 1]就很容易地做到。同样地,在二维空间中,某一图形如果不使用二维的齐次坐标,则只能旋转和伸缩,却不能平移。

     因此,我们在3D坐标中使用齐次坐标,是为了物体在矩阵变换中,除了伸缩旋转,还能够平移,如下运算:

 

既然了解了使用齐次坐标的意义,我们下一步就要了解一下齐次坐标w是什么意义。设w=1,此时相当于我们把3D的坐标平移搬去了w=1的平面上,4D空间的点投影到w=1平面上,齐次坐标映射的3D坐标是(x/w,y/w,z/w),也就是(x,y,z)。(x,y,z)在齐次空间中有无数多个点与之对应。所有点的形式是(kx,ky,kz,k),其轨迹是通过齐次空间原点的“直线”(其实每个点相当于3D的坐标世界)。 

当w=0时,有很大的意义,可解释为无穷远的“点”,其意义是描述方向。这也是平移变换的开关,当w=0时,

此时不能平移变换了。这个现象是非常有用的,因为有些向量代表“位置”,应当平移,而有些向量代表“方向”,如表面的法向量,不应该平移。从几何意义上说,能将第一类数据当作"点",第二类数据当作"向量"。可以通过设置w的值来控制向量的意义。

 

【转】 http://blog.csdn.net/rabbitguiming/archive/2009/03/06/3964140.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值