精华内容
下载资源
问答
  • 齐次坐标和矩阵变换

    2010-11-07 13:57:00
    一直对齐次坐标这个概念的理解...特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hil...
     一直对齐次坐标这个概念的理解不够彻底,只见大部分的书中说道“齐次坐标在仿射变换中非常的方便”,然后就没有了后文,今天在一个叫做“三百年 重生”的博客上看到一篇关于透视投影变换的探讨的文章,其中有对齐次坐标有非常精辟的说明,特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hill, JR。

         由于作者对齐次坐标真的解释的不错,我就原封不动的摘抄过来:

         对于一个向量v以及基oabc可以找到一组坐标(v1,v2,v3),使得v = v1 a + v2 b + v3 c          1

     而对于一个p,则可以找到一组坐标(p1,p2,p3),使得 po = 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、缩放S3个最常见的仿射变换,平移变换只对于点才有意义,因为普通向量没有位置概念,只有大小和方向.

     

    而旋转和缩放对于向量和点都有意义,你可以用类似上面齐次表示来检测。从中可以看出,齐次坐标用于仿射变换非常方便。

     

    此外,对于一个普通坐标的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也是很有研究的,要想成为一名专业的计算机图形学学习者,除了知其然必须还得知其所以然。这样在遇到问题的时候才能迅速定位问题的根源,从而解决问题。

     

     

     

    首先,谈到矩阵,就离不开坐标变换,而3D坐标变换的基础是来源于线性代数。以下摘抄自孟岩的blog:
    1 线性空间中的任何一个对象,通过选取基和坐标的办法,都可以表达为向量的形式。这里只要把基看成是线性空间里的坐标系就可以了。在线性空间中选定基之后,向量刻画对象,矩阵刻画对象的运动,用矩阵与向量的乘法施加运动。所以,矩阵的本质是运动的描述。
    2 矩阵是线性空间中的线性变换的一个描述。在一个线性空间中,只要我们选定一组基,那么对于任何一个线性变换,都能够用一个确定的矩阵来加以描述。
    3 矩阵不仅可以作为线性变换的描述,而且可以作为一组基的描述。而作为变换的矩阵,不但可以把线性空间中的一个点给变换到另一个点去,而且也能够把线性空间中的一个坐标系(基)表换到另一个坐标系(基)去。而且,变换点与变换坐标系,具有异曲同工的效果。线性代数里最有趣的奥妙,就蕴含在其中。

    我们先讨论3*3矩阵:
    1 矩阵的行序和列序(也称行优先或列优先)仅仅是指矩阵的存储方式,即我们如果用一个4*4数组m存储矩阵,如果m[0][0]-m[0][3]连续存储了矩阵的第一行,那么就是行优先,反之就是列优先。无论是行优先还是列优先,它们代表的数学意义是相同的。
    2 如果矩阵是行序,那么它的第一列(m[0][0],m[1][0],m[2][0])就代表X变换,第二列就是Y变换,第三列就是Z变换。
      我们来看看为什么:
    刚才提到矩阵把线性空间中的一个点给变换到另一个点,不妨称变换前的点为P1(x1,y1,z1),变换后的点为P2(x2,y2,z2):
    那么根据线代中的矩阵乘法,P1 * M = P2展开就成了:
    x2 = x1*m[0][0] + y1*m[1][0] + z1*m[2][0];
    y2 = x1*m[0][1] + y1*m[1][1] + z1*m[2][1];
    z2 = x1*m[0][2] + y1*m[1][2] + z1*m[2][2];
    看出什么了吗?
    如果把一个行序矩阵(接下来讨论的都是行序矩阵,就省略行序二字了)的每一列分别用X,Y,Z三个矢量来表示,那么M就表示为:XYZ三根轴。
    现在,矩阵M看起来是不是很像一个坐标系?而P1到P2的变换就是P1分别与X,Y,Z的点积!
    也就是矩阵M是把P1从老坐标系变换到新坐标系,而矩阵的三列(三根轴)就分别代表了新坐标系的三根轴在老坐标系中的坐标!
    而点积的几何意义其实就是求取投影!所以坐标变换的几何本质(刚才已经讨论过其代数本质),就是把一个点分别投影到三根轴上去而已!
    再仔细想一想,P1在XYZ三根轴上的投影,不正是它在新坐标系下的坐标吗?这样一来,坐标变换是不是就太容易理解了呢?
    3 所以缩放矩阵M的三根轴,XYZ的模就不等于1,如果某一根轴的模不等于1,那么就有了对应的缩放。所以纯旋转矩阵,前三列的模必然等于1。
    4 DX的矩阵是行序,OpenGL的矩阵是列序。我写的引擎,S3D的矩阵也是行序的。

    最后说说4*4矩阵:
    1 刚才讨论了旋转和缩放,平移如何表示呢?
      x2 = x1*m[0][0] + y1*m[1][0] + z1*m[2][0] + Xt;
    这里Xt就是表示x方向上的平移。Xt,Yt,Zt共同构成了一个4*4矩阵的第4行的前3列。
    2 4*4矩阵的第4列初始情况下一般设置为0,0,0,1,这些值也被称为W,它代表了近大远小的比例关系。此时需要被变换的点(矢量),也必须增加一个元素,成为x,y,z,w,而w的初始值设置为1。注意这里的xyzw并不是四元数的概念,这里的w仅仅是为了配合4*4矩阵运算而存在的。
    3 4*4矩阵实际上是为了把多步坐标变换并置而产生的,矩阵并置后可以用一个4*4矩阵代表多次坐标变换,从而显著提高顶点变换的效率。而且参与变换的W最终还可以用于透视校正和深度测试。
    4 对于4*4矩阵的上三角阵(3*3矩阵)的理解,可以完全沿用刚才3*3矩阵的讨论。

    注1:几何流水线坐标变换基本流程:  Local->World->View->Projection->Homo->Viewport->Screen
    注2:如果一个矩阵变换是线性的,那么它的转置与求逆等价。我们经常在一些逆变换(比如ShadowMap算法)中看到转置,不必疑惑,它的意义仍然是求逆。
    注3:矩阵运算不满足交换律,所以会出现一些有趣的结果,比如M1代表一个旋转操作,M2代表一个平移操作,那么 P*M1*M2 就是先旋转再平移,而P*M2*M1就成了先平移在旋转。我们在实际3D编码中经常遇到这样的问题,就是一个物体是以自己为参照物旋转,还是以世界为参照物旋转,那么按照刚才的描述,假如Mw表示世界变换矩阵,如果Mw左乘M1,再作为最终变换矩阵,那么就是以自己为参照物旋转(很容易理解,因为是先旋转,才变换到世界坐标系嘛,所以这个旋转是定义在本地的),而如果Mw右乘M1,就是先变换到世界坐标系,再旋转了,这时当然就是以以世界为参照物旋转了。
    注4:几个最基本的矩阵表达式,感兴趣的可以自己推导一下:
    // | x 0 0 0 |
    // | 0 y 0 0 |
    // | 0 0 z 0 |
    // | 0 0 0 1 | 缩放

    // | 1 0 0 0 |
    // | 0 1 0 0 |
    // | 0 0 1 0 |
    // | x y z 1 | 平移

    // | 1  0 0 0 |
    // | 0  c s 0 |
    // | 0 -s c 0 |
    // | 0  0 0 1 | X旋转 s,c表示旋转角的sin,cos值,下同

    // | c 0 -s 0 |
    // | 0 1  0 0 |
    // | s 0  c 0 |
    // | 0 0  0 1 | Y旋转

    // |  c s 0 0 |
    // | -s c 0 0 |
    // |  0 0 1 0 |
    // |  0 0 0 1 | Z旋转

    // | Sx*Sy*Sz + Cy*Cz Cx*Sz Sx*Cy*Sz - Sy*Cz 0 |
    // | Sx*Sy*Cz - Cy*Sz Cx*Cz Sx*Cy*Cz + Sy*Sz 0 |
    // |            Cx*Sy   -Sx            Cx*Cy 0 |
    // |                0     0                0 1 | ZXY旋转的并置

     

    转载于:https://www.cnblogs.com/lizhengjin/archive/2010/11/07/1871055.html

    展开全文
  • 齐次坐标

    2020-05-19 21:49:05
    齐次坐标  在数学里,齐次坐标(homogeneous coordinates),或投影坐标(projective coordinates)是指一个用于投影几何里的坐标系统。该词由奥古斯特·费迪南德·...使用齐次坐标可让计算机进行仿射变换,通常其投

    一、背景

        在数学里,齐次坐标(homogeneous coordinates),或投影坐标(projective coordinates)是指一个用于投影几何里的坐标系统。该词由奥古斯特·费迪南德·莫比乌斯于1827年在其著作《Der barycentrische Calcul》一书内引入。
      齐次坐标可让包括无穷远点的点坐标以有限坐标表示。使用齐次坐标的公式通常会比用笛卡儿坐标表示更为简单,且更为对称。齐次坐标广泛的应用于计算机图形及3D计算机视觉。使用齐次坐标可让计算机进行仿射变换,通常其投影变换能简单地使用矩阵来表示。
      在齐次坐标的定义中,一个点的齐次坐标乘上一个非零标量,所得坐标会表示同一个点。因此齐次坐标也用来表示无穷远点,为此一扩展而需用来表示坐标的数值比投影空间的维度多一。

    二、齐次坐标与笛卡尔坐标

        在齐次坐标里,需要两个值来表示在投影线上的一点,需要三个值来表示投影平面上的一点。则点 (X,Y)(X, Y) 在齐次坐标里面变成了 (x,y,w)(x, y, w) ,并且有 X=x/wX = x/wY=y/wY = y/w 。笛卡尔坐标系下 (12)(1,2) 的齐次坐标可以表示为 (1,2,1)(1, 2, 1) ,如果点 (1,2)(1, 2) 移动到无限远处,在笛卡尔坐标下它变为 (,)(∞, ∞),然后它的齐次坐标表示为 (1,2,0)(1, 2, 0) ,因为 (10,20)=(,)(\frac{1}{0}, \frac{2}{0}) = (∞, ∞),我们可以不用 来表示一个无穷远处的点。下面为齐次坐标与笛卡尔坐标的转换关系。

      齐次坐标 \qquad \qquad \quad 笛卡尔坐标
    (x,y,w)   <=>(xw,yw)=(X,Y)(x, y, w) \ \ \ <=> \quad (\frac{x}{w}, \frac{y}{w}) \quad =\quad (X, Y)

    (1,2,1)<=>(11,21)=(1,2)(1, 2, 1) \quad <=> \quad (\frac{1}{1}, \frac{2}{1}) \quad =\quad (1, 2)

    (2,4,2)<=>(22,42)=(1,2)(2, 4, 2) \quad <=> \quad (\frac{2}{2}, \frac{4}{2})\quad = \quad (1, 2)
     

    三、进阶

        实投影平面可以看作是一个具有额外点的欧氏平面,这些点称之为无穷远点,并被认为是位于一条新的线上(该线称之为无穷远线)。每一个无穷远点对应至一个方向(由一条线之斜率给出),可非正式地定义为一个点自原点朝该方向移动的极限。在欧氏平面里的平行线可看成会在对应其共同方向的无穷远点上相交。正如生活中两条平行的铁轨会在视觉的无穷远处相交。给定欧氏平面上的一点 (x,y)(x, y),对任意非零实数 ZZ,三元组 (xZ,yZ,Z)(xZ, yZ, Z) 即称之为该点的齐次坐标。依据定义,将齐次坐标内的数值乘上同一个非零实数,可得到同一点的另一组齐次坐标。例如,笛卡儿坐标上的点 (1,2) 在齐次坐标中即可标示成 (1,2,1)(1,2,1)(2,4,2)(2,4,2)。原来的笛卡儿坐标可透过将前两个数值除以第三个数值取回。因此,与笛卡儿坐标不同,一个点可以有无限多个齐次坐标表示法。
      一条通过原点 (0,0)(0, 0) 的线之方程可写作 nx+my=0nx + my = 0,其中 nnmm 不能同时为 0。以参数表示,则能写成 x=mt,y=ntx = mt, y = − nt。令 Z=1tZ=\frac{1}{t},则线上的点之笛卡儿坐标可写作 (mZ,nZ)(\frac{m}{Z},\frac{-n}{Z})。在齐次坐标下,则写成 (m,n,Z)(m, − n, Z)。当 tt 趋向无限大,亦即点远离原点时,ZZ 会趋近于 0,而该点的齐次坐标则会变成 (m,n,0)(m, −n, 0)。因此,可定义 (m,n,0)(m, −n, 0) 为对应 nx+my=0nx + my = 0 这条线之方向的无穷远点的齐次坐标。因为欧氏平面上的每条线都会与透过原点的某一条线平行,且因为平行线会有相同的无穷远点,欧氏平面每条线上的无穷远点都有其齐次坐标。
    概括来说:

    • 投影平面上的任何点都可以表示成一三元组 (X,Y,Z)(X, Y, Z),称之为该点的齐次坐标投影坐标,其中 XYX、YZZ 不全为 0。
    • 以齐次坐标表表示的点,若该坐标内的数值全乘上一相同非零实数,仍会表示该点。
    • 相反地,两个齐次坐标表示同一点,当且仅当其中一个齐次坐标可由另一个齐次坐标乘上一相同非零常数得取得。
    • ZZ 不为 0,则该点表示欧氏平面上的该 (XZ,YZ)(\frac{X}{Z}, \frac{Y}{Z})
    • ZZ 为 0,则该点表示一无穷远点。
      注意,三元组 (0,0,0)(0, 0, 0) 不表示任何点。原点表示为 (0,0,1)(0, 0, 1)

    在这里插入图片描述

    线段与投影平面示意图

    在这里插入图片描述
    有理贝兹曲线-定义于齐次坐标内的多项式曲线(蓝色),以及于平面上的投影-有理曲线(红色)W 为投影平面

    参考资料:
    [1] 关于齐次坐标的理解:https://blog.csdn.net/janestar/article/details/44244849
    [2] 齐次坐标:https://zh.wikipedia.org/wiki/%E9%BD%90%E6%AC%A1%E5%9D%90%E6%A0%87

    欢迎关注个人公众号,实时推送最新博文!
    在这里插入图片描述

    展开全文
  • Core Graphics框架中的图形变换 在Core Graphics框架图形绘制的时候,经常会有对图形进行平移、缩放...CGAffineTransform与齐次坐标 首先,我们先看一下CGAffineTransform这个结构体是什么样子的,如下所示. struct CG..


    Core Graphics框架中的图形变换


    在Core Graphics框架图形绘制的时候,经常会有对图形进行平移、缩放、旋转这样的要求.那么我们该如何实现呢?这就需要Core Graphics框架中的CGAffineTransform(矩阵)这个结构体来进行实现了.下面我们就对CGAffineTransform这个矩阵结构体,进行逐一的说明.


    CGAffineTransform与齐次坐标


    首先,我们先看一下CGAffineTransform这个结构体是什么样子的,如下所示.

    struct CGAffineTransform {
      CGFloat a, b, c, d;
      CGFloat tx, ty;
    };
    
    

    为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准.也就是z轴.是不发生改变的。接下来呢,我们就使用齐次坐标来表示这个结构体.如下所示.

    |a  b  0|
    
    |c  d  0|
    
    |tx ty 1|
    
    

    现在我们就看一下用齐次坐标是如何表示一个坐标的仿射变换的,假设现在有坐标 [X ,Y,1],运算原理如下所示.

                   |a  b  0|
    
      [X,Y,  1]    |c  d  0|   =  [aX + cY + tx   bX + dY + ty  1] ;
    
                    |tx ty 1|
    
    

    那么平移、缩放、旋转是怎么执行的呢?其实很简单,这三种形式的变换不过是齐次坐标的几个特殊情况,下面我们就一一道来.

    平移变换

    ######条件: a = d = 1 ,b = c = 0.
    条件如上所述,接下来我们看一下坐标 [X ,Y,1]与我们设定好的齐次坐标的叉积会发生什么样的变化.

                   |1  0  0|
    
      [X,Y,  1]    |0  1  0|   =  [X + tx   ,  Y + ty  , 1] ;
    
                    |tx ty 1|
    
    

    那么的坐标就变成了 [X + tx , Y + ty , 1],与原坐标相比,z轴没发生任何的改变,但是x轴方向平移了tx个单位,y轴方向平移了ty个单位.

    那么如果我们把这种特殊情况进行封装,我们就得到了我们的平移函数.

    CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty)
    

    缩放变换

    ######条件: b = c = 0 ,tx = ty = 0.
    如平移变换一致,我们把条件输入进去,看一下坐标 [X ,Y,1]与我们设定好的齐次坐标的叉积会发生什么样的变化.

                   |a  0  0|
    
      [X,Y,  1]    |0  d  0|   =  [aX  ,  dY  ,1] ;
    
                    |0 0 1|
    
    

    那么的坐标就变成了[aX , dY ,1],与原坐标相比,z轴仍然没发生任何的改变,但是x轴方向缩放了a倍,y轴方向缩放了d倍.

    那么如果我们把这种特殊情况进行封装,我们就得到了我们的缩放函数.注意一点的是使用缩放函数的时候,sx和sy如果不想让其改变就设置为1,而不是0.

    GAffineTransformMakeScale(CGFloat sx, CGFloat sy)
    

    旋转变换
    条件 : tx=ty=0,a=cosɵ,b=sinɵ,c=-sinɵ,d=cosɵ

    跟上面的两种情况一样,我们首先条件带入我们的齐次坐标里面,看一下结果如何.

                   |cosɵ   sinɵ  0|
    
      [X,Y,  1]    |-sinɵ  cosɵ  0|   = [Xcosɵ - Ysinɵ ,   Xsinɵ + Ycosɵ , 1] ;
    
                    |tx     ty    1|
    
    

    这个时候,ɵ就是旋转的角度,逆时针为正,顺时针为负。

    那么如果我们把这种特殊情况进行封装,我们就得到了我们的缩放函数.

    CGAffineTransformMakeRotation(CGFloat angle)
    

    CGAffineTransform的使用


    上面,我们已经对仿射变换有了大体的了解,知道了它的原理,那么接下来我们就做一个简单Demo.来看一下在Core Graphics框架中是如何使用仿射变换函数的.

    首先还是创建SDView继承与UIView类.

    我们依然在drawInRect:这个方法中进行我们的操作.我们在方法中先在图形上下文中绘制一个矩形.代码如下.

        //获取图形上下文
        CGContextRef context = UIGraphicsGetCurrentContext();
    
    
        //创建路径
        CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), nil);
        
        
        //添加路径
        CGContextAddPath(context, path);
        
        //设置颜色
        CGContextSetRGBStrokeColor(context, 1.0, 0, 0, 1);
        
        //绘制
        CGContextDrawPath(context, kCGPathFillStroke);
    
        //删除路径
        CGPathRelease(path);
    
    

    接下来我们直接在ViewController中添加SDView这个视图.

    #import "ViewController.h"
    #import "SDView.h"
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        SDView *view = [[SDView alloc]initWithFrame:self.view.frame];
        
        view.backgroundColor = [UIColor whiteColor];
        
        [self.view addSubview:view];
        
    }
    
    @end
    
    

    效果如下.

    上面绘制的矩形是没有经过任何图形变换的.接下来我们就在drawInRect:这个方法中创建三种仿射变换.代码如下.

        //创建平移变化结构体
        CGAffineTransform translationAffineTransform = CGAffineTransformMakeTranslation(100, 0);
        
        //创建缩放变化结构体
        CGAffineTransform scaleAffineTransform = CGAffineTransformMakeScale(3, 0);
        
        //创建缩放变化结构体
        CGAffineTransform rotationAffineTransform = CGAffineTransformMakeRotation(M_PI_2);
    

    紧接着,我们就把创建路径这个代码替换成有仿射变换的路径.(当然了,我们要把多余的注释掉嗷~~)

    //    //创建路径
    //    CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), nil);
    //    
        //创建路径(平移)
        CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &translationAffineTransform);
        
        //创建路径(缩放)
        CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &scaleAffineTransform);
        
        //创建路径(旋转)
        CGPathRef path = CGPathCreateWithRect(CGRectMake(100, 100, 100, 100), &rotationAffineTransform);
    

    下面我们就看一下三种仿射变换的效果图.

    平移变换

    缩放变换

    旋转变换



    Core Graphics框架仿射变换就说这么多了,后期,最后双手奉上Demo.
    –>仿射变换Demo传送门💾
    展开全文
  • 齐次坐标概念&&透视投影变换推导 透视投影是3D固定流水线的重要组成部分,是将相机空间中的点从视锥体(frustum)变换到规则观察体(Canonical View Volume)中,待裁剪完毕后进行透视除法的行为。在算法中它是通过透视...
  • 齐次坐标理解

    2019-03-13 09:54:38
    一直对齐次坐标这个概念的理解...特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hill...

    一直对齐次坐标这个概念的理解不够彻底,只见大部分的书中说道“齐次坐标在仿射变换中非常的方便”,然后就没有了后文,今天在一个叫做“三百年 重生”的博客上看到一篇关于透视投影变换的探讨的文章,其中有对齐次坐标有非常精辟的说明,特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hill, JR。

       由于作者对齐次坐标真的解释的不错,我就原封不动的摘抄过来:
    
       对于一个向量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也是很有研究的,要想成为一名专业的计算机图形学的学习者,除了知其然必须还得知其所以然。这样在遇到问题的时候才能迅速定位问题的根源,从而解决问题。

    展开全文
  • 齐次坐标的理解

    2019-11-02 09:46:41
    齐次坐标的理解 一直对齐次坐标这个概念...特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F...
  • 在机器人及自动驾驶中,经常用齐次变换矩阵将旋转和平移进行统一。 前面的文章也介绍过齐次变换矩阵,本文算是一个总结。1. SE(3)将旋转矩阵和平移向量写在同一个矩阵中,形成的矩阵,称为special Euclidean group,...
  • 齐次坐标的含义

    2019-07-29 15:15:07
    齐次坐标点的表示: why:有了笛卡尔坐标,我为什么还要使用齐次坐标呢? 在做旋转和缩放的时候,如果采用笛卡尔坐标的话,可以直接乘以旋转角度和缩放尺度就可以对图片进行处理,但是如果做平移变换的时候,笛卡尔...
  • 对于齐次坐标的理解

    2021-04-01 11:48:14
    特别是针对这样一句话进行了有力的证明:“齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射(线性)几何变换。”—— F.S. Hill, JR。 由于作者对齐次坐标真的...
  • 齐次坐标的物理含义

    千次阅读 2017-11-29 18:32:11
    齐次坐标表示是计算机图形学的重要手段之一,它既能够用来明确区分向量和点,同时也更易用于进行仿射几何变换。”—— F.S. Hill, JR 在计算机图形学中,其变换引入齐次坐标更方便计算。2.齐次坐标在计算机图形学...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 307
精华内容 122
关键字:

齐次坐标进行变换