⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tutorial_30.htm

📁 如果你相信它就好好学学吧,同样这里也只是个入门
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><!-- 这篇文章由Dancingwind翻译,作者的联系方式zhouwei02@mails.tsinghua.edu.cn --><title>NeHe OpenGL教程第三十课,DancingWind翻译</title>





<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style type="text/css">
A:link {COLOR: #ccaaff; TEXT-DECORATION: none}
A:visited {COLOR: #ccaaff; TEXT-DECORATION: none}
A:active {COLOR: #ccaaff; TEXT-DECORATION: none}
A:hover {COLOR: #ffccaa; TEXT-DECORATION: none}
</style></head><body bgcolor="#000000" text="#ffffff"><br><br>

<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td height="130" width="326"><img src="Tutorial_30_files/logo.png" height="130" width="326"></td>
    <td align="center" valign="middle" width="75%"><font color="#ffccaa" size="+3"><b><i>第30课</i></b></font></td>
  </tr></tbody></table>
  <!-- 上边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
  <tr>
    <td><img src="Tutorial_30_files/tl.jpg" height="28" width="28"></td>
    <td width="100%"><img src="Tutorial_30_files/tc.gif" height="28" width="100%"></td>
    <td><img src="Tutorial_30_files/tr.gif" height="28" width="28"></td>
  </tr>
</tbody>
</table>

<!-- 中部-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
  <tr>
  	<!-- 中部左边框-->
    <td background="Tutorial_30_files/l.gif"><img src="Tutorial_30_files/l.gif" height="28" width="28"></td>
	<!-- 中部文字部分-->
    <td valign="top" width="100%">
	<table border="0" width="100%">
          <tbody><tr>
            <td width="28%"><img src="Tutorial_30_files/lesson30.jpg" height="180" width="240"></td>
            <td width="72%"><p><font class="head">碰撞检测:</font></p>
              <p><font size="3">这是一课激动的教程,你也许等待它多时了。你将学会碰撞剪裁,物理模拟太多的东西,慢慢期待吧。</font></p></td>
          </tr>
     </tbody></table>
      </td>
	<!-- 中部右边框-->
    <td background="Tutorial_30_files/r.gif"><img src="Tutorial_30_files/r.gif" height="28" width="28"></td>
  </tr>
</tbody>
</table>

<!-- 下边框-->
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
  <tr>
    <td><img src="Tutorial_30_files/bl.gif" height="28" width="28"></td>
    <td width="100%"><img src="Tutorial_30_files/bc.gif" height="28" width="100%"></td>
    <td><img src="Tutorial_30_files/br.gif" height="28" width="28"></td>
  </tr>
</tbody>
</table>
  <table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_30_files/l.png"><img src="Tutorial_30_files/l.png"></td>
    <td valign="top" width="100%">碰撞检测和物理模拟(作者:Dimitrios Christopoulos (christop@fhw.gr))<br> 
      <br> <b><u>碰撞检测</u></b> <br> <br>
      这是一个我遇到的最困难的题目,因为它没有一个简单的解决办法.对于每一个程序都有一种检测碰撞的方法.当然这里有一种蛮力,它适用于各种不同的应用,当它非常的费时.<br>
      我们将讲述一种算法,它非常的快,简单并易于扩展.下面我们来看看这个算法包含的内容:<br> <br>
      1) 碰撞检测 
      <ul>
        <li>移动的球-平面</li>
        <li>移动的球-圆柱</li>
        <li>移动的球-移动的球</li>
      </ul>
      2) 基于物理的建模 
      <ul>
        <li>碰撞表示</li>
        <li>应用重力加速度</li>
      </ul>
      3) 特殊效果 
      <ul>
        <li>爆炸的表示,利用互交叉的公告板形式</li>
        <li>声音使用Windows声音库</li>
      </ul>
      4) 关于代码 
      <ul>
        <li>代码被分为以下5个部分</li>
      </ul>
      <table border="0">
        <tbody><tr> 
          <td>Lesson30.cpp</td>
          <td>&nbsp;</td>
          <td>: 主程序代码l</td>
        </tr>
        <tr> 
          <td>Image.cpp,</td>
          <td>Image.h</td>
          <td>: 加载图像</td>
        </tr>
        <tr> 
          <td>Tmatrix.cpp,</td>
          <td>Tmatrix.h</td>
          <td>: 矩阵</td>
        </tr>
        <tr> 
          <td>Tray.cpp,</td>
          <td>Tray.h</td>
          <td>: 射线</td>
        </tr>
        <tr> 
          <td>Tvector.cpp,</td>
          <td>Tvector.h</td>
          <td>: 向量</td>
        </tr>
      </tbody></table>
      <p><br>
        <br>
        1) 碰撞检测 <br>
        <br>
        我们使用射线来完成相关的算法,它的定义为: <br>
        <br>
        <i>射线上的点 = 射线的原点+ t * 射线的方向</i> <br>
        <br>
        t 用来描述它距离原点的位置,它的范围是[0, 无限远). <br>
        <br>
        现在我们可以使用射线来计算它和平面以及圆柱的交点了。<br>
        <br>
        射线和平面的碰撞检测: <br>
        <br>
        平面被描述为:<br>
        <br>
        <i>Xn dot X = d</i> <br>
        <br>
        Xn 是平面的法线.<br>
        X 是平面上的一个点.<br>
        d 是平面到原点的距离. <br>
        <br>
        现在我们得到射线和平面的两个方程: <br>
        <br>
        <i>PointOnRay = Raystart + t * Raydirection<br>
        Xn dot X = d</i> <br>
        <br>
        如果他们相交,则上诉方程组有解,如下所示:<br>
        <br>
        <i>Xn dot PointOnRay = d</i> </p>
      <p><i>(Xn dot Raystart) + t * (Xn dot Raydirection) = d</i> <br>
        <br>
        解得 t: <br>
        <br>
        <i>t = (d - Xn dot Raystart) / (Xn dot Raydirection)</i> <br>
        <br>
        t代表原点到与平面相交点的参数,把t带回原方程我们会得到与平面的碰撞点.如果Xn*Raydirection=0。则说明它与平面平行,则将不产生碰撞。如果t为负值,则说明交点在射线的相反方向,也不会产生碰撞<font face="Tahoma,Verdana,sans-serif" size="-1">。</font></p></td>
    <td background="Tutorial_30_files/r.png"><img src="Tutorial_30_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
<pre><font color="#ffffaa" size="3">//判断是否和平面相交,是则返回1,否则返回0</font><br>int TestIntersionPlane(const Plane&amp; plane,const TVector&amp; position,const TVector&amp; direction, double&amp; lamda, TVector&amp; pNormal)<br>{</pre>

<p> double DotProduct=direction.dot(plane._Normal);<br>
  double l2;</p>
<p> <font color="#ffffaa" size="3">//判断是否平行于平面</font><br>
  if ((DotProduct&lt;ZERO)&amp;&amp;(DotProduct&gt;-ZERO)) <br>
  return 0;</p>
<p> l2=(plane._Normal.dot(plane._Position-position))/DotProduct;</p>
<p> if (l2&lt;-ZERO) <br>
  return 0;</p>
<p> pNormal=plane._Normal;<br>
  lamda=l2;<br>
  return 1;<br>
  }</p>
  </font>
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_30_files/l.png"><img src="Tutorial_30_files/l.png"></td>
    <td valign="top" width="100%"><font face="Tahoma,Verdana,sans-serif" size="-1"> <font size="+1"><u>射线-圆柱的碰撞检测</u></font> 
      <br>
      <br>
      </font>计算射线和圆柱方程组得解。</td>
    <td background="Tutorial_30_files/r.png"><img src="Tutorial_30_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/br.png" height="28" width="28"></td></tr></tbody></table><font color="#aaffaa" size="3"><pre>int TestIntersionCylinder(const Cylinder&amp; cylinder,const TVector&amp; position,const TVector&amp; direction, double&amp; lamda, TVector&amp; pNormal,TVector&amp; newposition)
</pre></font><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/tl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/tc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/tr.png" height="28" width="28"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td background="Tutorial_30_files/l.png"><img src="Tutorial_30_files/l.png"></td>
    <td valign="top" width="100%">球-球之间的碰撞检测<br> <br>
      球被表示为中心和它的半径,决定两个球是否相交就是求出它们之间的距离是否小于它们的直径。<br> <br>
      在处理两个移动的球是否相交时,有一个bug就是,当它们的移动速度太快,回出现它们相交,但在相邻的两步检测不出它们是否相交的情况,如下图所示:<br> 
      <br> <center>
        <img src="Tutorial_30_files/figure1.jpg"><br>
        图 1 
      </center>
      <br> <br>
      有一个替代的办法就是细分相邻的时间片断,如果在这之间发生了碰撞,则确定有效。我们把这个细分时间段设置为3,代码如下:<font face="Tahoma,Verdana,sans-serif"> 
      <center>
      </center>
      </font></td>
    <td background="Tutorial_30_files/r.png"><img src="Tutorial_30_files/r.png"></td></tr></tbody></table><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="Tutorial_30_files/bl.png" height="28" width="28"></td><td width="100%"><img src="Tutorial_30_files/bc.png" height="28" width="100%"></td><td><img src="Tutorial_30_files/br.png" height="28" width="28"></td></tr></tbody></table>
<font color="#aaffaa" size="3">
</font><pre><font color="#aaffaa" size="3"><font color="#ffffaa">//判断球和球是否相交,是则返回1,否则返回0</font><br>int FindBallCol(TVector&amp; point, double&amp; TimePoint, double Time2, int&amp; BallNr1, int&amp; BallNr2)<br>{<br>	TVector RelativeV;<br>	TRay rays;<br>	double MyTime=0.0, Add=Time2/150.0, Timedummy=10000, Timedummy2=-1;<br>	TVector posi;<br>	<br>	<font color="#ffffaa">//判断球和球是否相交</font><br>	for (int i=0;i&lt;NrOfBalls-1;i++)<br>	{<br>	 for (int j=i+1;j&lt;NrOfBalls;j++)<br>	 {	<br>		    RelativeV=ArrayVel[i]-ArrayVel[j];<br>			rays=TRay(OldPos[i],TVector::unit(RelativeV));<br>			MyTime=0.0;</font></pre>

<p><font color="#aaffaa" size="3"> if ( (rays.dist(OldPos[j])) &gt; 40) continue; </font></p>
<p><font color="#aaffaa" size="3"> while (MyTime&lt;Time2)<br>
  {<br>
  MyTime+=Add;<br>
  posi=OldPos[i]+RelativeV*MyTime;<br>
  if (posi.dist(OldPos[j])&lt;=40) {<br>
  point=posi;<br>
  if (Timedummy&gt;(MyTime-Add)) Timedummy=MyTime-Add;<br>
  BallNr1=i;<br>
  BallNr2=j;<br>
  break;<br>
  }<br>
  <br>
  }<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -