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

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

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

      零基礎制作物理引擎--創造力量

      2016-01-07 09:41  【當耐特】  閱讀(5921)  評論(6)    收藏  舉報

      寫在前面

      上篇其實有重力,但是重力是經過重心,可以把物體看出質點,問題就變得簡單,經過重心只產生線速度,不產生角速度。

      這篇文章的力量其實是指:力(Force)和沖量(Impulse),不一定過重心。

      邊寫引擎過程中,邊補習牛頓經典力學體系,但是依然記得大學時候物理老師反復強調:“牛頓錯了,牛頓錯了,牛頓那一套只是狹義相對論在低速下的近似表現”。

      所以順帶又科普了一下愛因斯坦那一套東西,后來發現,寫個物理引擎用牛頓足矣。= =!

      目標

      本篇目標是為剛體新增兩個方法,一個是創造力,一個是創造沖量。
      創造力:

      applyForce: function (force, point) {
      
      }
      
      • 參數一:force是一個Vector2對象的實例,代表了力的沿著x、y方向上的大小。
      • 參數二:point是施力點的世界坐標

      創造沖量

      applyImpulse: function (impulse, point) {
      
      }
      
      • 參數一:impulse是一個Vector2對象的實例,代表了沖量的沿著x、y方向上的大小。
      • 參數二:point是施放沖量點的世界坐標

      準備工作

      知識準備

      沖量和時間的關系

      I = F * t

      圓盤轉動慣量

      m * r * r / 2 (r為半徑)

      長方體轉動慣量

      m*(a * a + b * b)/ 12 (a和b分別為長和寬)

      更多轉動慣量,請參見: https://en.wikipedia.org/wiki/List_of_moments_of_inertia

      I * L / 轉動慣量 = 角加速度 (L為力矩長度)

      轉動慣量越大,對轉動的抵抗就越大,就越難讓其旋轉。

      圖解

      假設一個剛體收到沖量I:

      usage

      沖量I可以拆分成3個沖量分量,I1、I2、I3,其中:

      • I1產生X軸和Y軸方向線速度
      • I2產生角速度和Y軸方向線速度
      • I3產生角速度和X軸方向線速度

      過重心,作一條垂直于I2的垂線,垂線的長度(力矩長度)乘以 沖量分量I2 除以 轉動慣量 = 角加速度,

      過重心,作一條垂直于I3的垂線,垂線的長度(力矩長度)乘以 沖量分量I3 除以 轉動慣量 = 角加速度,

      I2和I3產生的角加速度需求累加。

      程序

      applyImpulse: function (impulse, point) {
          var rA = point.clone().sub(this.position);
          //如果不通過重心
          if (rA.x !== 0 || rA.y !== 0) {
              var nv = rA.clone().normalize();
              var tangent = new Newton.Vector2(nv.y, -nv.x);
      
              var ni = nv.multiply(nv.x * impulse.x + nv.y * impulse.y);
              this.linearVelocity.x += ni.x * this.invMass;
              this.linearVelocity.y += ni.y * this.invMass;
      
              var tni = tangent.multiply(tangent.x * impulse.x + tangent.y * impulse.y);
              this.linearVelocity.x += tni.x * this.invMass;
              this.linearVelocity.y += tni.y * this.invMass;
              this.angularVelocity += (rA.x * tni.y - rA.y * tni.x) * this.invRotationalInertia;
          } else {  //如果過重心
              this.linearVelocity.x += impulse.x * this.invMass;
              this.linearVelocity.y += impulse.y * this.invMass;
          }
      }
      

      上面有個條件分支,當沖量的方向經過重心的時候,只產生線速度。

      因為轉動慣量的倒數和質量的倒數使用非常頻繁,所以在構造函數內就提前計算好,如圓的構造函數里提前求好了轉動慣量的倒數:

      Newton.Circle = Newton.Body.extend({
          ctor: function (option) {
              this._super(option);
              this.r = option.r;
              this.rSqu = this.r * this.r;
              this.type = Newton.CIRCLE;
              this.invRotationalInertia = 2 / (this.mass * Math.pow(this.r , 2));
          }
      });
      

      同樣,在矩形的構造函數里,也提前求出來轉動慣量的倒數:

      this.invRotationalInertia = 12 / (this.mass * (Math.pow(this.width, 2) + Math.pow(this.height, 2)));
      

      但是需要注意的是,如果質量發生改變的話,轉動慣量也需要發生相應改變,所以可以使用Object.defineProperty()去定義mass,在set里面改變invRotationalInertia。

      有了上面的applyImpulse方法,封裝applyForce就會簡單許多:

      applyForce: function (force, point) {
          this.applyImpulse(force.clone().multiply(Newton.World.TimeStep),point);
      }
      

      沖量等于力在時間上的累加,這里提供的力的時間長度為最小時間片段。

      簡化代碼

      通過Vector2的cross方法可以把applyImpulse簡化成如下代碼:

      applyImpulse: function (impulse, point) {
          var rA = point.clone().sub(this.position);
          this.linearVelocity.add(impulse.clone().multiply(this.invMass));
          this.angularVelocity += this.invRotationalInertia * rA.cross(impulse);
      }
      

      舉個例子

      var world = new Newton.World();
      Newton.World.Gravity.y=0;
      
      var box = new Newton.Rectangle({
          width: 70,
          height:30,
          position: new Newton.Vector2(100, 300),
          linearVelocity: new Newton.Vector2(0, 0),
          angularVelocity:0
      });
      world.add(box);
      
      document.querySelector("#ourCanvas").addEventListener("click",function(evt){
          box.applyImpulse(new Newton.Vector2(200,-250),new Newton.Vector2(box.position.x-10,box.position.y-10))
      }, false);
      
      var render = new Newton.Render("#ourCanvas");
      world.onTick(function () {
          render.clear();
          render.rect(box.position.x, box.position.y, box.width, box.height, box.rotation);
      })
      
      world.start();
      

      這里把重力加速度設成了0,角速度和線速度都是0,所有在100,300的位置能夠看到一個靜止的矩形。當點擊Canvas的時候,
      在剛體重心的左上方10個像素的位置施加右上(200,-250)的沖量,可以看到它如下圖所示的方式飛出去:

      usage

      最后

      因為多邊形的轉動慣量和重心計算要比圓形和矩形復雜一下,這里先不展開,待物理引擎骨架基本建立之后再做完善。
      未完待續...

      主站蜘蛛池模板: 国产肥臀视频一区二区三区| 粗壮挺进人妻水蜜桃成熟 | 欧美成人精品三级网站视频| 激情综合网激情国产av| 麻豆国产传媒精品视频| 欧美人成在线播放网站免费| 亚洲欧美精品在线| 亚洲国产中文字幕精品| 夜爽8888视频在线观看| 成年黄页网站大全免费无码| 亚洲综合伊人久久大杳蕉| 亚洲午夜亚洲精品国产成人| 亚洲香蕉伊综合在人在线| 国产真人性做爰久久网站| 99午夜精品亚洲一区二区| 国产美女高潮流白浆视频| 日韩精品国产二区三区| 性一交一乱一乱一视频| 免费夜色污私人影院在线观看| 激情综合网激情五月我去也| 少妇高潮喷潮久久久影院| 且末县| 国产亚洲综合区成人国产| 日夜啪啪一区二区三区| 一级做a爰片久久毛片下载| 色就色中文字幕在线视频| 中文字幕国产在线精品| 色欲狠狠躁天天躁无码中文字幕| 日韩幕无线码一区中文| 子长县| 日韩深夜福利视频在线观看| 欧美人禽zozo动人物杂交| 日本xxxx色视频在线播放| 狠狠做五月深爱婷婷天天综合| 国产女人看国产在线女人| 99er热精品视频| 亚洲AV日韩精品久久久久| 成人午夜av在线播放| 日韩不卡手机视频在线观看| 蜜桃av亚洲精品一区二区| 色偷偷女人的天堂亚洲网|