关于椭球碰撞检测的思考
<p>如有转载, 请注明出处:<br/><a href="http://www.azure.com.cn/" target="_blank">http://www.azure.com.cn/</a></p><p>近日突然变得的比较清闲,这样我就可以仔细想想以前没有想清楚的问题。</p><p>椭球碰撞是现今比较高效的一种方法。看了老外的一篇论文,<<<b>Improved Collision detection and Response</b>>>, 发现老外说一个事情非常罗嗦, 最前面还把线性代数的知识讲了一遍, 看完了才发现是大学课本上的知识. 便马上跳过了.<br/>实际碰撞中, 将椭球包裹住角色, 能产生比较好的吻合.这样碰撞效果更加的精确了.<br/>这里我所思考的范围还不涉及碰撞后的滑动, 那是我下一步要思考的 .</p><p>这里我主要总结下, 椭球碰撞的几个要点:</p><p>1. 椭球的表示:</p><p>这里说的椭球都是正椭球, 是没有倾斜的那种(如果考虑倾斜的就超级复杂了 ), 用三个半径 X, Y, Z, 和一个中心点坐标P来表示.如下图:</p><p><img src="UploadFile/2007-5/20075822845734.gif" border="0" alt=""/></p><p>在这个图里, 三个半径分别是 X=3, Y=7, Z=3</p><p>2. 计算椭球下一次位置</p><p>只有发生移动才能发生碰撞, 当然只用把椭球的中心坐标P改变位移即可.<br/>P' = P + v</p><p>3. 根据新中心坐标P', 把待碰撞检测的三角形变换到椭球空间中来(重点)</p><p>假设待碰撞检测的三角形三个顶点为a, b, c. 在那个论文中, 作者大肆炫耀他的数学知识, 总是把一个非常简单的问题解释的又臭又长. 说了半天线性代数中基础基的问题, 赚取了不少的稿费. <br/>其实这个椭球空间的转换再简单不过了.<br/>我们假设转换后的顶点为a', b', c'</p><p>那么有<br/>a' = CBM * (a - P')<br/>b' = CBM * (b - P')<br/>c' = CBM * (c - P') <br/>其中CBM是一个转换矩阵<br/>[ 1/X 0 0]<br/>[ 0 1/Y 0]<br/>[ 0 0 1/Z]<br/>还记得吗, X,Y,Z是上图椭球的三个半径.</p><p>这样转换后, 椭球就变成了一个处在原点, 半径为1的正球了(想不过来,仔细想想 )<br/>待检测的三角形(a' b' c')就被变换到原点附近, 这样就只用判断其与这个半径为1正球的关系就可以知道是否发生碰撞了. </p><p>4. 开始碰撞检测了</p><p>I. 首先粗略排除绝对不可能相交的.<br/>通过变换后三点(a' b' c')形成一个平面 Plane, 首先判断此平面到原点的距离, 如果大于1则绝对不可能与此待检测的三角形发生碰撞, 在这里你可以直接从你的检测函数中退出了. 当距离小于或者等于1, 再跳到步骤II.</p><p>II. 判断是否有任意一点在单位球内.<br/>这也是个快速剔除的方法, 如果a' b' c' 任意一点到原点的距离小于1, 则发生碰撞了, 如果都不小于1, 则我们需要转到第III步, 进行次昂贵的相交测试运算.</p><p>III. 边与单位球的相交检测<br/>对于三角形 a' b' c' , 它有三条边a'b', b'c', c'a', 那么我们检测原点到三条边的距离, 如果有任意一条小于1, 则发生了碰撞, 如果非常遗憾的都不小于1的话, 我们就进入最昂贵的第四步的碰撞检测.</p><p>IV. 最后一步<br/>在前面第一步, 我们已经计算出来了a'b'c' 组成的平面Plane, 这里第一步首先计算出从原点作垂线到Plane的垂足的坐标. 然后判断此坐标是否在a'b'c'组成的三角形内. 如果在内, 则碰撞发生, 如果不在内, 则无碰撞发生.</p><p><br/>5. 是否应该移动到下个位置呢.</p><p>我们可以把3,4步集成到一个函数 bool collide(vec3 newpos)中, 如果我们把P'传进去发生碰撞了, 那么我们第2步的坐标改变则不可以发生, 如果不考虑滑动的话, 则不改变位移,停在原地算了.如果没有发生碰撞, 则我们可以大大方方改变原来椭球的中心坐标了, 也就是物体可以向前移动了.当然如果移动速度过快, 会发生穿墙的问题. 这个问题暂时还没有想到如何解决, 如果哪位想到了, 也可以告诉我. 谢谢.</p><p>总结:</p><p>以上的讲解, 并未提供详细的代码, 关于如何求到面的距离, 到直线的距离, 也不在这里的讨论范围内, 这些算法网上非常多, 在那篇老外的论文中, 后面也提供了相关的代码, 大家可以去看看.</p>[此贴子已经被作者于2007-5-8 22:08:46编辑过]
页:
[1]