The Matrix

The Matrix
丁欧南
 

Keyword:[3D Math][Matrix][矩阵操作]

在这篇文章里我将介绍三个矩阵,分别对应于OpenGL中的glTranslate,glRotate,glScale.虽然OpenGL中的这三个函式操作起来很方便,但我认为学习矩阵的内部原理,一方面有利于更好地理解3D程式的思维方式,正所谓under the hood;另一方面使你能够得心应手地驾驭3D程式写作的一些高级技巧(如Cg).
这篇学习笔记出自我这样一个初学者之手,我希望通过此文与诸位共进步.
 
A. 基础(IMO)
  矩阵(Matrix)本质上就是这样一种东西:方便的坐标系统转换器.
  为什么把它称之为坐标系统转换器呢?我举一个实际的例子:
 
  任务: 给出n个顶点,现要求以某直线axis为轴将这些顶点旋转π/6
 
  解法1:为每个顶点重新计算它的新位置,并修改原先的代码.

        即 glVertex3f(0,1,0); 改为 glVertex3f(0.5,sqrt(3)/2,0);

  解法2:在旧顶点与新顶点之间建立映射关系.vertex’=f(vertex)

        源代码无需修改,只要在实际渲染前把旧顶点坐标映射到新顶点坐标即可.

  解法2就是矩阵的思维.解法2与解法1在效果上完全相同.也就是说: 矩阵为你所提供的
  服务就是:坐标转换自动化,除此之外同手工效果一样.

B. 约定
  使用纯系坐标系统(Homogeneous Coordinate)
  平移部分位于最后一行(row)
  这样做的目的是使你能把所见之矩阵无需修改,直接写入你的OpenGL代码

  [a11  a12  a13  a14]

  [a21  a22  a23  a24]

  [a31  a32  a33  a34]

  [a41  a42  a43  a44]

  GLfloat matrix[]={a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44};

 
  叉积(Cross Product): × 点积(Dot Product): *


C. 右手定则
  1.OpenGL右手坐标系统
    伸出右手,伸出拇指,食指,中指,且中指与食指垂直.这时中指,拇指,食指分别对应OpenGL坐标的x,y,z的正方向.
  2.叉积右手定则
    伸出右手,四指并拢,拇指竖直向上
    P×Q
    如果右手手指沿P,手掌面对着Q,那么拇指就指出了P×Q的方向
  3.旋转右手定则
    伸出右手,四指握住要旋转的轴,拇指朝向轴的正方向,向身体内侧转动手腕,这时旋转的角定为正角
 
D. 平移(Translate)
  只要将原顶点加上要平移的距离即可.

  [1   0   0   0]

  [0   1   0   0]

  [0   0   1   0]

  [sx  sy  sz   1]

 
E. 旋转(Rotate)
E1 绕X轴旋转

  [1      0      0      0]

  [0      cosθ  sinθ   0]

  [0      -sinθ  cosθ  0]

  [0      0      0      1]

E2 绕Y轴旋转

  [cosθ  0      -sinθ  0]

  [0      1      0      0]

  [sinθ   0      cosθ  0]

  [0      0      0      1]

E3 绕Z轴旋转

  [cosθ  sinθ   0      0]

  [-sinθ  cosθ   0     0]

  [0      0      1      0]

  [0      0      0      1]


 

E3 绕任意轴旋转
  我假定此轴一定过原点,否则我可以用D中提到的平移矩阵将此轴移到原点.
           

 


 

    V up⊥V perp  |V up|=|V perp|=|V aux|  V proj⊥V perp  n∥V proj  n为单位向量

     绕n旋转V θ度到V’, 求V’

    
     V proj=|V proj|/|n| n

     n*V=|n||V|cosβ     cosβ=|Vproj|/|V|   |Vproj|=|V|cosβ

     n*V=|n||V proj|         |V proj|=(n*V)/|n|

     Vproj=(n*V)/|n|2 n       因为 n 为单位向量

     所以 Vproj=n*V n

    

     Vperp=V-Vproj=V-n*V n

     V up=V perp×n=(V-n*V n)×n=V×n-n*V(n×n)=V×n
    
     V aux=-sin(θ-90)V perp+cos(θ-90)V up=sin(90-θ)V perp+cos(90-θ)V up
        =cosθV perp+sinθV up=cosθ(V-n*V n)+sinθ(V×n)
    

     V’=Vperp+Vaux=n*v n+cosθ(V-n*V n)+sinθ(V×n)

 
 
F 缩放(Scale)

   已知  被缩放向量 V    缩放方向 n (Normaled)  V,n交角θ Vperp ⊥ Vproj 缩放倍数 s  求V’

                    

 

 

    Vproj=|Vproj|/|n| n     cosθ=|Vproj|/|V|

   所以  cosθ|V| =|Vproj|

   n*V=cosθ|V| |n| = |Vproj| |n|     |Vproj­| = n*V/|n|

   代入第一个式子: V­proj = n*V/|n|2 n  又n已是单位向量

   所以  Vproj = n*V n      Vtarget = s Vproj =s n*V n

   Vperp = V-Vproj = V-n*V n

  

   V’=Vtarget+Vperp = s n*V n+V-n*V n = V+(V*n)(s-1)n


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值