<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      碼農(nóng)干貨系列【1】--方向包圍盒(OBB)碰撞檢測

      2012-06-07 11:40  【當(dāng)耐特】  閱讀(34133)  評論(23)    收藏  舉報

      干貨

      最近一直在刪文章,不是要關(guān)博洗手什么的,而是被刪的文章沒有達(dá)到“干貨”的標(biāo)準(zhǔn)。干貨的反義詞是水貨,比如我們經(jīng)常吃的注水豬肉,它就是水貨,非干貨。什么是“干貨”。?經(jīng)過一番搜尋,標(biāo)準(zhǔn)的描述是:實用性比較強的,不含任何吹噓水分,也沒有虛假的成分,所以業(yè)內(nèi)人士通常把這一類分享活動稱之為“干貨”。

      文章是否是干貨做如下幾點要求:

      必備條件:

      1.整體樣式風(fēng)格整齊美觀;

      2.實用性比較強的,邏輯條理清晰;

      3.獨立性強,一篇文章只寫一類東西;

      4.碼農(nóng)看完就懂(或者有了search的方向),拿去就能用;

      加精條件:

      1.圖文并茂;

      2.在線演示;

      3.示例代碼下載;

      從這篇開始我們的干貨之旅~~~~~

      簡介

      包圍體是一個簡單的幾何空間,里面包含著復(fù)雜形狀的物體。為物體添加包圍體的目的是快速的進(jìn)行碰撞檢測或者進(jìn)行精確的碰撞檢測之前進(jìn)行過濾(即當(dāng)包圍體碰撞,才進(jìn)行精確碰撞檢測和處理)。包圍體類型包括球體、軸對齊包圍盒(AABB)、有向包圍盒(OBB)、8-DOP以及凸殼。如圖1所示。

      clip_image001

      圖1 依次是球體、AABB、OBB

      可以看到圖1是3D包圍體,在2D包圍體如圖2所示:
      clip_image003

      圖2 依次是球體、AABB、OBB

       

      OBB

      方向包圍盒(Oriented bounding box),簡稱OBB。方向包圍盒類似于AABB,但是具有方向性、可以旋轉(zhuǎn),AABB不能旋轉(zhuǎn)。如圖3所示。

      clip_image005

      圖3 矩形和矩形投影檢測的四條軸

      要計算兩個OBB是否碰撞,只需要計算他們在圖3上的4個坐標(biāo)軸上的投影是否有重疊,如果有,則兩多邊形有接觸。這也可以擴展到任意多邊形,如圖4所示。

      clip_image007

      圖4 矩形和三角形投影檢測的五條軸

      投影軸來自于多邊形自身邊的垂線。

      判定方式:兩個多邊形在所有軸上的投影都發(fā)生重疊,則判定為碰撞;否則,沒有發(fā)生碰撞

      OBB存在多種的表達(dá)方式,這里使用最常用的一種:一個中心點、2個矩形的邊長、兩個旋轉(zhuǎn)軸(該軸垂直于多邊形自身的邊,用于投影計算)。代碼如下所示:

      (function (window) {

      var OBB = function (centerPoint, width, height, rotation) {

      this.centerPoint = centerPoint;
      this.extents = [width / 2, height / 2];
      this.axes = [new Vector2(Math.cos(rotation), Math.sin(rotation)), new Vector2(-1 * Math.sin(rotation), Math.cos(rotation))];

      this._width = width;
      this._height = height;
      this._rotation = rotation;
      }

      window.OBB = OBB;
      })(window);

      其所依賴的Vector2這個類如下所示:

      (function (window) {
      Vector2 = function (x, y) {
      this.x = x || 0;
      this.y = y || 0;
      };

      Vector2.prototype = {
      sub: function (v) {
      return new Vector2(this.x - v.x, this.y - v.y)
      },
      dot: function (v) {
      return this.x * v.x + this.y * v.y;
      }
      };
      window.Vector2 = Vector2;
      } (window))

      然后基于這個數(shù)據(jù)結(jié)構(gòu),進(jìn)行OBB之間的相交測試。為OBB擴展一個方法,即或者在任意軸上的投影半徑:

      OBB.prototype = {
      getProjectionRadius: function (axis) {
      returnthis.extents[0] * Math.abs(axis.dot(this.axes[0])) + this.extents[1] * Math.abs(axis.dot(this.axes[1]));
      }
      }

      這里你可能需要讀者了解Vector2.dot的幾何意義:若b為單位矢量,則a與b的點積即為a在方向b的投影

      有了這些,就可以進(jìn)行相交檢測。由上面的判定方式,可以得出,兩個矩形之間的碰撞檢測需要判斷四次(每個投影軸一次)。完整檢測代碼如下所示:

      (function (window) {

      var CollisionDetector = {

      detectorOBBvsOBB: function (OBB1, OBB2) {
      var nv = OBB1.centerPoint.sub(OBB2.centerPoint);
      var axisA1 = OBB1.axes[0];
      if (OBB1.getProjectionRadius(axisA1) + OBB2.getProjectionRadius(axisA1) <= Math.abs(nv.dot(axisA1))) return false;
      var axisA2 = OBB1.axes[1];
      if (OBB1.getProjectionRadius(axisA2) + OBB2.getProjectionRadius(axisA2) <= Math.abs(nv.dot(axisA2))) return false;
      var axisB1 = OBB2.axes[0];
      if (OBB1.getProjectionRadius(axisB1) + OBB2.getProjectionRadius(axisB1) <= Math.abs(nv.dot(axisB1))) return false;
      var axisB2 = OBB2.axes[1];
      if (OBB1.getProjectionRadius(axisB2) + OBB2.getProjectionRadius(axisB2) <= Math.abs(nv.dot(axisB2))) return false;
      return true;

      }
      }

      window.CollisionDetector = CollisionDetector;
      })(window)

      這里拿兩個OBB的中心點連線在坐標(biāo)軸上的投影長度和兩個矩形投影半徑之和進(jìn)行對比,如果半徑之后都小于或者等于中心連線之后才判定為碰撞,否則判定為分離狀態(tài)。

      集成圖形化測試接口

      為了更加直觀的測試OBB碰撞檢測方法,使用Easeljs輸出碰撞的狀態(tài)。當(dāng)兩個矩形沒有發(fā)生碰撞的時候,兩矩形呈現(xiàn)藍(lán)色;當(dāng)兩個矩形發(fā)生碰撞的時候,兩矩形呈現(xiàn)紅色。先引入相關(guān)的腳本庫以及用于顯示的canvas畫布:

      <script src="Vector2.js" type="text/javascript"></script>
      <script src="OBB.js" type="text/javascript"></script>
      <script src="CollisionDetector.js" type="text/javascript"></script>
      <script src="easel.js" type="text/javascript"></script>
      <canvas id="testCanvas" width="980" height="580">
      

      然后進(jìn)行OBB初始化以及碰撞檢測:

      var OBB1, OBB1x = 100, OBB1y = 150, OBB1w = 30, OBB1h = 140, OBB1r = 30;
      var OBB2, OBB2x = 100, OBB2y = 70, OBB2w = 40, OBB2h = 110, OBB2r = 40;
      var canvas;
      var stage;
      var color;

      function init() {

      canvas = document.getElementById("testCanvas");
      stage = new Stage(canvas);

      Ticker.addListener(window);
      }

      function tick() {
      stage.removeAllChildren();

      OBB1r += 2;
      OBB2r += 1;
      OBB1 = new OBB(new Vector2(OBB1x, OBB1y), OBB1w, OBB1h, OBB1r * Math.PI / 180);
      OBB2 = new OBB(new Vector2(OBB2x, OBB2y), OBB2w, OBB2h, OBB2r * Math.PI / 180);
      var r = CollisionDetector.detectorOBBvsOBB(OBB1, OBB2);

      color=r?"red":"#00F";
      OBB1 = new Container();
      stage.addChild(OBB1);
      OBB1.x = OBB1x;
      OBB1.y = OBB1y;
      var frame1 = new Shape();
      frame1.graphics.beginFill(color).drawRect(0, 0, OBB1w, OBB1h);
      frame1.rotation = OBB1r;
      frame1.regX = OBB1w / 2;
      frame1.regY = OBB1h / 2;
      OBB1.addChild(frame1);

      OBB2 = new Container();
      stage.addChild(OBB2);
      OBB2.x = OBB2x;
      OBB2.y = OBB2y;
      var frame2 = new Shape();
      frame2.graphics.beginFill(color).drawRect(0, 0, OBB2w, OBB2h);
      frame2.rotation = OBB2r;
      frame2.regX = OBB2w / 2;
      frame2.regY = OBB2h / 2;
      OBB2.addChild(frame2);

      stage.update();
      }
      init();

      以上代碼定義了兩個旋轉(zhuǎn)的OBB包圍盒,當(dāng)他們發(fā)生碰撞則改變繪制的顏色,使其成為紅色。運行代碼,效果圖5和6所示。

      clip_image009

      圖5 未發(fā)生碰撞

      clip_image011

      圖6 發(fā)生碰撞

      這里是2D情況下的OBB碰撞檢測,對于3D OBB碰撞檢測,更為復(fù)雜。需要測試15個分離軸以確定OBB的相交狀態(tài),兩個OBB的坐標(biāo)軸各3個,以及垂直于每個軸的9個軸。除了坐標(biāo)軸個數(shù)不一樣,其相交測試思路和本文一致,本文不再探討。

      在線演示

      更多干貨敬請期待~~~~~

      主站蜘蛛池模板: 国产一区二区精品久久岳| 2020中文字字幕在线不卡| 粉嫩jk制服美女啪啪| 成人无遮挡裸免费视频在线观看| 欧美色丁香| 深夜福利啪啪片| 漂亮人妻中文字幕丝袜| 国产热A欧美热A在线视频| 国精偷拍一区二区三区| 日产中文字幕在线精品一区| 精品视频一区二区三区不卡| 日韩成人精品一区二区三区| 少妇粗大进出白浆嘿嘿视频| 亚洲一区二区约美女探花| 国产亚洲精品久久77777| 亚洲国产精品久久久天堂麻豆宅男| 国产精品美女黑丝流水| 国产一区二区三区av在线无码观看 | 久热这里只有精品视频六| 蜜桃av亚洲精品一区二区| 欧美人与动牲交a免费| 亚洲综合一区国产精品| 老子午夜精品无码| 女人爽到高潮的免费视频| 五月天国产成人av免费观看| 99久久er热在这里只有精品99| 日韩高清亚洲日韩精品一区二区| 国产色悠悠视频在线观看| 99精品人妻少妇一区| 国产精品无遮挡又爽又黄| gogogo高清免费观看| 国产午夜亚洲精品福利| 国产精品呻吟一区二区三区| 午夜AAAAA级岛国福利在线| 在线综合亚洲欧洲综合网站| 国产精品呻吟一区二区三区| 男人和女人做爽爽视频| 男人一天堂精品国产乱码| xxxx丰满少妇高潮| 郑州市| 4480yy亚洲午夜私人影院剧情|