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

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

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

      碼農干貨系列【2】--由關節(Joint)說到割繩子(cut the rope)

      2012-06-08 08:03  【當耐特】  閱讀(5020)  評論(14)    收藏  舉報

      簡介

      關節是相互連結且互相約束的物體,常見于各類物理引擎當中。關節的運用非常廣泛,例如人體模擬、動物行走模擬、器材、繩子、機關、鏈橋等都可以靈活利用關節去模擬。

      image 普通的關節分兩種,一種是有固定點,一種沒有固定點。本文分別對兩種關節進行計算并且輸出圖片進行模擬。

      關節

      關節通常用下面這種表達方式:

      (function (window) {
      var Joint = function (segLength, segCount, isFixed, startPoint) {
      this.segLength = segLength;
      this.segCount = segCount;
      this.isFixed = isFixed;
      this.startPoint = startPoint;
      this.points = [];
      for (var i = 0; i < this.segCount; i++) {
      this.points.push(new Vector2(this.startPoint.x, this.startPoint.y + i * this.segLength));
      }
      }
      window.Joint = Joint;
      } (window))

      其中:

      segLength表示關節每一段的長度(這里假定關節每一段是相等的)

      segCount表示關節個數(包括起點和終點)

      isFixed表示關節是否有固定點(如果isFixed為true,假設startPoint為固定點)

      startPoint表示關節的起點(這里假定關節的初始狀態是筆直向下的)

      points表示關節上所有的支點(包括起點和終點)

      這里需要了解的是 ,在完整的關節表示當中,為了更好的模擬現實世界當中的物體,關節還會加上一個角度區間限制,即關節的最大張開角度和最小的角度。本文的關節不加此限制,任其360度無障礙旋轉。

      圖形化輸出

      這里使用Easeljs輸出關節的圖像。先引用相關的腳本:

          <script src="script/Vector2.js" type="text/javascript"></script>
          <script src="script/joint.js" type="text/javascript"></script>
          <script src="script/easel.js" type="text/javascript"></script>
      

      定義一個擁有2個關節段,每段長度為60的關節。完整代碼如下所示:

      var joint = new Joint(60,4,false,new Vector2(200,100));
      var canvas;
      var stage;
      var shape;
      (function (){
      canvas = document.getElementById("testCanvas");
      stage = new Stage(canvas);

      shape = new Shape();
      stage.addChild(shape);
      drawjoint(joint);
      }())

      function drawjoint(joint) {
      shape.graphics.clear();
      shape.graphics.ss(14, 'round', 'round');
      for (var i = 0; i < joint.points.length - 1; i++) {
      if (i % 2 === 0) {
      shape.graphics.beginStroke("green");
      }
      else {
      shape.graphics.beginStroke("red");
      }
      shape.graphics.mt(joint.points[i].x, joint.points[i].y).lt(joint.points[i + 1].x, joint.points[i + 1].y);
      }
      shape.graphics.endStroke();
      stage.update();
      }

      效果如圖所示:
      image

      與鼠標交互

      要讓關節繞著對應的支點動起來,這里讓關節的終點跟隨鼠標的位置移動。

      在方法中加入:

      canvas.onmousemove = canvasMouseMoveHandler; 

      所以,當鼠標移動的時候,需要實時的更新關節的位置。如下圖所示:

      image

      這里需要注意的兩點是:

      上圖描述的是一次微小的拉動,真正要呈現如圖所示的前后狀態,其實已經經歷的很多次位置更新

      上圖反向延長線經過初始點是不準確的,準確的位置是初始點靠右一段距離(取決于兩條線段的合力方向,但這不影響關節的模擬)

      image

      添加鼠標處理的方法:

      function canvasMouseMoveHandler(e) {
      var r = canvas.getBoundingClientRect();
      joint.points[joint.points.length - 1] = new Vector2(e.clientX - r.left, e.clientY - r.top);
      joint.updatePointsPosition(joint.points[joint.points.length - 1], joint.points.length - 1);
      drawjoint(joint);
      }

      在分析完具體的過程之后,利用遞歸的思路依次更新所有的點。更新方法接收兩個參數:一個是更新的點、一個是該點的index,當index為1的時候退出遞歸。


      var p = Joint.prototype;
      p.updatePointsPosition = function (point, index) {
      var tempV = this.points[index - 1].sub(point).setLength(this.segLength);
      this.points[index - 1] = point.add(tempV);
      if (index > 1) {
      this.updatePointsPosition(this.points[index - 1], index - 1);
      }
      }

      其中var tempV = this.points[index - 1].sub(point).setLength(this.segLength);是計算支點的偏移量,Vector2.setLength是經過normalize(轉換為該向量的單位向量) 再multiplyScalar(設置長度)。如下代碼所示:

      setLength: function (l) {

      return this.normalize().multiplyScalar(l);

      },
      完整代碼參見Vector2類。
      運行效果如下所示:
      請使用現代瀏覽器觀看在線演示!

      固定起始點

      上面呈現的是沒有固定點的關節,那么如果擁有固定點,該怎么更新關節上所有點的位置呢?需要做的僅僅是校正startPoint(啟始點、固定點)的位置。

      var p = Joint.prototype;
      p.updatePointsPosition = function (point, index) {
      var tempV = this.points[index - 1].sub(point).setLength(this.segLength);
      this.points[index - 1] = point.add(tempV);
      if (index > 1) {
      this.updatePointsPosition(this.points[index - 1], index - 1);
      } else {
      if (this.isFixed) {
      var v = this.points[0].sub(this.startPoint);
      for (var i = 0; i < this.points.length; i++) {
      this.points[i].subSelf(v);
      }
      }
      }
      }

      當遞歸到最后,如果該關節是有固定點的,校正所有關節點的位置。效果如下所示:

      請使用現代瀏覽器觀看在線演示!

      思考??

      這樣子呢?

      var joint = new Joint(2,140,true,new Vector2(200,100));

      一共140個點,點與點之間距離為2,再加上點顏色區間變化。

      請使用現代瀏覽器觀看在線演示!

      它是割繩子(cut the rope)中繩子的表達方式嗎?這樣表示繩子會有什么問題出現?

      那么請繼續關注我后續的干貨~~~~~

      主站蜘蛛池模板: 99久久99久久精品免费看蜜桃| 国产睡熟迷奷系列网站| 午夜福利国产区在线观看| 男女扒开双腿猛进入爽爽免费看| 一区二区中文字幕久久| 人妻系列中文字幕精品| 女人色熟女乱| 日韩无专区精品中文字幕| 忘忧草社区在线www| 国内自拍小视频在线看| 99久久激情国产精品| 日本欧美大码a在线观看| 开心激情站开心激情网六月婷婷| 人妻丝袜无码专区视频网站 | 国产一区二区三区自拍视频| 亚洲精品日韩在线观看| 午夜成人无码免费看网站| 99国产精品白浆在线观看免费 | 国产精品无遮挡猛进猛出| 亚洲产在线精品亚洲第一站一| 无码人妻精品一区二区三区66| 久草热在线视频免费播放| 91精品国产免费人成网站| 国产区精品福利在线观看精品| 国产无遮挡吃胸膜奶免费看| 黑人巨大精品欧美一区二区| 国产成人亚洲精品成人区| 国产精品久久中文字幕| 亚洲AV国产福利精品在现观看| 狠狠综合久久av一区二| 国产精品理论片| 国产成人精品永久免费视频| 人妻激情偷乱一区二区三区| 亚洲人成色99999在线观看| 91精品91久久久久久| 狠狠色综合网站久久久久久久| 内射合集对白在线| 欧美日韩一区二区三区视频播放| 久久精品一区二区三区综合| 亚洲精品一区二区天堂| 鲁丝一区二区三区免费|