您现在的位置: 中国IT实验室 >> 游戏开发 >> 开发文档 >> 文章正文
向量几何在游戏编程中的使用(二)
来源:中国IT实验室 作者:佚名 时间:2007-5-10

  <2>2-D物体任意角度的反弹

  -Twinsen编写

  -本人水平有限,疏忽错误在所难免,还请各位数学高手、编程高手不吝赐教

  -我的Email-address: popyy@netease.com

  第一次我说了一下向量知识的基础内容和一点使用技巧,浅显的展示了它在游戏编程中的作用。这次深入一些,充分利用向量的性质模仿一个物理现象。

  首先,我要介绍一下将要使用的两个基本但非常重要的技巧。

  一、求与某个向量a正交的向量b

  根据向量内积的性质以及正交向量之间的关系,有:

  设a=(xa,ya),b=(xb,yb)

  a.b = 0

  => xa*xb + ya*yb = 0

  => xa*xb = -ya*yb

  => xa/-ya = yb/xb

  => xb = -ya , yb = xa 或 xb = ya , yb = -xa

  则向量(xa,ya)的正交向量为(xb,yb)=(-ya,xa)

  比如上图中,向量(2,3)的逆时针旋转90度的正交向量是(-3,2),顺时针旋转90度的正交向量为(3,-2)。

  这样,任给一个非零向量(x,y),则它相对坐标轴逆时针转90度的正交向量为(-y,x),顺时针转90度的正交向量为(y,-x)。

  二、计算一个向量b与另一向量a共线的两个相反的投影向量

 

  我们看一下上面的图,很明显,cosA(A=X)关于y轴对称,是偶函数,因此cosA = cos(-A),

  又因为cosA是周期函数,且周期是2*PI,则有cos(A+2*PI) = cosA = cos(-A) = cos(-A+2*PI),

  则根据cosA = cos(2*PI-A)以及a.b = |a|*|b|*cosA,有

  a.b = |a|*|b|*cosA = |a|*|b|*cos(2*PI-A)

 

  现在,根据上图,就有a.b = |a|*|b|*cosA = |a|*|b|*cos(2*PI-A) = ax*bx + ay*by

  按照这个规则,当上面的b与c的模相等时,有|a|*|b| = |a|*|c|,进一步的,当它们与a的夹角A = B时,就有

  a.b = |a|*|b|*cosA = |a|*|c|*cosB = a.c ,相应的有

  a.b = |a|*|b|*cosA = |a|*|b|*cos(2*PI-A) = |a|*|c|*cosB = |a|*|c|*cos(2*PI-B) = a.c 也就是

  ax*bx + ay*by = ax*cx + ay*cy

  我们还注意到在一个周期内,比如在[0,2*PI]中,cosA有正负两种情况,分别是:在(0,PI/2)&(3*PI/2, 2*PI)为正,在(PI/2,3/2*PI)为负。好,知道了这件事情之后,再看a.b = |a|*|b|*cosA,|a|和|b|都为正,所以a.b的正负性就由cosA决定,换句话说,a.b与它们夹角A的余弦cos有相同的符号。所以,还看上面的图,我们就有:

  1)当A在(0, PI/2)&(3*PI/2, 2*PI)中,此时2*PI-A在(-PI/2,0)&(0, PI/2)中,a.b为正

  2)当A在(PI/2, 3*PI/2)中,此时2*PI-A也在(PI/2, 3*PI/2)中,a.b为负

  现在我们再来看一下同模相反(夹角为PI)向量b和b'与同一个向量a的两个内积之间有什么关系。

  首先B + B'= 2*PI - PI = PI,所以有b = -b', b' = -b,即

  (bx, by) = (-b'x, -b'y) = -(b'x, b'y)

  (b'x, b'y) = (-bx, -by) = -(bx, by)

  所以

  a.b =(ax, ay) . (bx, by) = (ax, ay) . -(b'x, b'y) = a.-b'= -(a.b')

  a.b'= (ax, ay) . (b'x, b'y) = (ax, ay) . -(bx, by) = a.-b = -(a.b)

  我们看到,一个向量b的同模相反向量b'与向量a的内积a.b',等于b与a的内积的相反数-(a.b)。

  好,有了上面的基础,我们就可以求一个向量b与另一向量a共线的两个相反的投影向量c和c'了。

 

  要求b在a上的投影向量c,我们可以用一个数乘上一个单位向量,这个单位向量要和a方向一至,我们记为a1.而这个数就是b在a上的投影长。

  先来求单位向量a1,我们知道它就是向量a乘上它自身长度的倒数(数乘向量),它的长度我们

  可以求出,就是m = sqrt(ax^2 + ay^2),所以a1就是(ax/m, ay/m),记为(a1x, a1y)。

  再求投影长/c/(注意//与||的区别,前者是投影长,可正可负也可为零,后者是实际的长度,衡为非负)。 根据内积的几何意义:一个向量b点乘另一个向量a1,等于b在a1上投影长与a1的长的乘积。那我们要求b在a上的投影长,就用它点乘a的单位向量a1就可以了,因为单位向量的长度为1,b的投影长/c/乘上1还等于投影长自身,即:

  /c/ = b.a1 = (bx, by) . (a1x, a1y) = bx * a1x + by * a1y

  好,我们得到了c的投影长,现在就可以求出c:

  c = /c/*a1 = ( (bx * a1x + by * a1y)*a1x, (bx * a1x + by * a1y)*a1y )

  总结一下,就是c = (b.a1)*a1.

  我们看到,b与a1的夹角在(0, PI/2)之间,因此它们的点积/c/是个正值。因此当它乘a1之后,得到向量的方向就是a1的方向。

  现在来看b',它是b的同模相反向量,它和a1的夹角在(PI/2, 3*PI/2)之间,因此b'点乘a1之后得到/c'/是个负值,它再乘a1,得到向量的方向和a1相反。我们知道,一个向量b的同模相反向量b'与向量a的内积a.b',等于b与a的内积的相反数-(a.b)。因此,/c'/ = -/c/,也就是说,它们的绝对值相等,符号相反。因此它们同乘一个a1,得到的的两个模相等向量c与c'共线。

  让我们把它完成:

  (b'.a1) = -(b.a1)

  => -(b'.a1) = (b.a1), 好,代入c = (b.a1)*a1,得到

  c = -(b'.a1)*a1

  => (b'.a1)*a1 = -c = c'

  c = ( b . a1 ) * a1 = (-b'. a1) * a1

  c'= ( b'. a1 ) * a1 = (-b . a1) * a1

  至此为止,我们得出结论:当一个向量b与另一个向量a的夹角在(0, PI/2)&(3*PI/2, 2*PI)之间,它在a方向上的投影向量c就是c = ( b . a1 ) * a1,其中a1是a的单位向量;它在a相反方向的投影向量c'是c'= ( b'. a1 ) * a1,其中向量b'是b的同模相反向量。

[1] [2] [3] 下一页  

收藏本文 责编:Kittoy 


相关文章
网络游戏的数据传输处理和防火墙穿透
新网游设计—(四)补充
新网游设计—(三)游戏概况
游戏开发工程实现方法理念
通过游戏策划阶段防治游戏外挂
推荐文章


 精彩友情推荐
·神州数码交换机
·神州数码交换机价格
·神州数码网络交换机
·netgear交换机
·网件交换机
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
 基础入门  开发文档
 最新推荐
  多数的Windows程序都需要Windows.h和Windowsx.h这两个头文件,要确保使用它们。当然,你还需要其它......
游戏引擎演化史
在Windows上安装OGRE的方法
关于滤镜遮罩概念,Sobel 遮罩
游戏开发新手入门之Windows编程
游戏开发新手入门之位图化图形
教你实现卡通渲染的另类勾边方法
游戏设计大师谈如何成为一名游戏设
Visual C#编写 3D游戏框架示例
真正的 Java 学习从入门到精通
游戏开发经验——游戏开发的基本常
  针对于移动新出台的政策,需要尽快地把我们公司的游戏对应到不同的手机平台,这是针对市场策略的有利调整............
Quake-III代码里神奇的浮点开方函数
基于Dialogue的MFC程序调用DirectX
关于Kjava手机平台移植可行性报告
网络游戏的数据传输处理和防火墙穿
浅谈网游的数据传输处理和防火墙穿
向量几何在游戏编程中的使用(六)
向量几何在游戏编程中的使用(五)
向量几何在游戏编程中的使用(四)
向量几何在游戏编程中的使用(三)
向量几何在游戏编程中的使用(二)
  培训中心