游戲裡面經常有轉盤活動, 為了讓轉盤表現自然一點, 就需要自己模擬阻尼運動, 分為三個過程: 勻加速運動, 勻速運動, 勻減速運動 設定最高速度為MaxSpeed, SpeedUp1(勻加速運動的加速度), SpeedUp2(勻減速運動的加速度), Expect(期望停留的弧度點) 其實模擬只需要把 ...
游戲裡面經常有轉盤活動, 為了讓轉盤表現自然一點, 就需要自己模擬阻尼運動, 分為三個過程: 勻加速運動, 勻速運動, 勻減速運動
設定最高速度為MaxSpeed, SpeedUp1(勻加速運動的加速度), SpeedUp2(勻減速運動的加速度), Expect(期望停留的弧度點)
其實模擬只需要把兩個加運動的區間模擬出來, 剩下的就是勻速運動的區間.
1 public struct DampingMotion 2 { 3 /// <param name="maxSpeed">最大速度</param> 4 /// <param name="speedUp1">加速運動1</param> 5 /// <param name="speedUp2">減速運動2</param> 6 /// <param name="expected">期望停留在某個弧度</param> 7 public Damping(double maxSpeed, double speedUp1, double speedUp2, double expected) 8 { 9 this.maxSpeed = maxSpeed; 10 this.speedUp1 = speedUp1; 11 this.speedUp2 = speedUp2; 12 this.expected = expected; 13 14 time1 = maxSpeed / speedUp1; 15 time3 = maxSpeed / speedUp2; 16 distance1 = speedUp1 * Math.Pow(time1, 2) / 2; 17 distance3 = speedUp2 * Math.Pow(time3, 2) / 2; 18 distance2 = expected - (distance1 + distance3) % (Math.PI * 2) + Math.PI * 4; 19 time2 = distance2 / maxSpeed; 20 } 21 22 //單位是秒 23 public double GetRotate(double time) 24 { 25 if (time >= 0 && time < time1) 26 { 27 return Math.Pow(time, 2) / 2 * speedUp1; 28 } 29 if (time >= time1 && time < time1 + time2) 30 { 31 return distance1 + (time - time1) * maxSpeed; 32 } 33 if (time >= time1 + time2 && time < time1 + time2 + time3) 34 { 35 var f = time - (time1 + time2); 36 return distance1 + distance2 + ( 37 speedUp2 * Math.Pow(time3, 2) / 2 - 38 speedUp2 * Math.Pow((time3 - f), 2) / 2 39 ); 40 } 41 return distance1 + distance2 + distance3; 42 } 43 44 public double maxSpeed; 45 public double speedUp1; 46 public double speedUp2; 47 public double expected; 48 49 public double time1; //第一段勻加速的時間 50 public double time2; //第二段勻速運動時間 51 public double time3; //第三段勻減速運動時間 52 private double distance1; 53 private double distance2; 54 private double distance3; 55 }
構造好之後, 只需要調用GetRotate函數, 就可以獲取某一個時間轉盤停留的弧度
這樣一個50行不到的代碼, 實際上可以當做一個面試題目