HTML5 Canvasで2つ以上のオブジェクト間に重力を実装する方法
HTML5 Canvas上で、2つ以上のオブジェクトの間に万有引力(重力)のような力を適用するには、ニュートンの万有引力の法則に基づいて、オブジェクト同士の距離と方向から力を計算し、それぞれの速度(vx・vy)へ加算します。
基本的な考え方
重力は「質量に比例し、距離の2乗に反比例する」引力です。この記事では簡略化のため、係数を 50 として扱っています。実際のシミュレーションでは、この値を調整することで引力の強さを変更できます。
計算の手順は以下の通りです。
- 2つのオブジェクト間の距離ベクトル(dx・dy)を求める
- 距離の2乗から力の大きさ F を計算する
- 単位ベクトル(方向成分 rhat_x・rhat_y)を求める
- 力を x 成分と y 成分に分解し、速度へ加える
実装コード
以下のコードは、ob1 と ob2 の2つのオブジェクト間に重力を適用する例です。
var distX = ob1.x - ob2.x, distY = ob1.y - ob2.y; var val = distX * distX + distY * distY; var r = Math.sqrt(val); var F = 50 / val; // 距離の2乗に反比例する力 var rhat_x = distX / r; var rhat_y = distY / r; var Fx = F * rhat_x; var Fy = F * rhat_y; ob1.vx += -Fx; ob1.vy += -Fy; ob2.vx += Fx; ob2.vy += Fy;
コードの解説
1. 距離ベクトルの計算
distX と distY は、2つのオブジェクトの中心座標の差です。これにより、一方から他方への向きがわかります。
2. 力の大きさの計算
val は距離の2乗(r²)です。F = 50 / val のように、距離の2乗で割ることで、遠いオブジェクトほど弱く引っ張り合う挙動になります。
3. 方向の正規化
rhat_x と rhat_y は長さ1の単位ベクトルで、力の「向き」だけを表します。ここに力の大きさ F を掛けることで、x・y 方向それぞれの力の成分(Fx・Fy)が求まります。
4. 速度への反映
作用・反作用の法則により、ob1 には逆向き(-Fx・-Fy)、ob2 には同じ向き(Fx・Fy)の力を加えます。これにより、2つのオブジェクトは互いに引き合うようになります。
3つ以上のオブジェクトへ拡張する
3つ以上のオブジェクトに対して重力を適用する場合は、すべてのペアの組み合わせに対して上記の計算を繰り返します。二重ループを使った実装例は次の通りです。
for (var i = 0; i < objects.length; i++) {
for (var j = i + 1; j < objects.length; j++) {
applyGravity(objects[i], objects[j]);
}
}
このように関数化しておけば、任意の数のオブジェクト間で重力シミュレーションを行えます。
注意点
- ゼロ除算に注意: 2つのオブジェクトが完全に重なると r = 0 となり、計算エラーが発生します。最小距離の下限を設けるなどの対策が必要です。
- 係数の調整: 「50」という値は引力の強さを表す定数です。シーンのスケールや求める動きに応じて変更してください。
- 時間ステップ: 毎フレームごとにこの計算を実行し、速度を元に位置を更新することで、自然な引力のアニメーションが実現します。
-
Day.jsを使って2つの時刻の差を求める方法【JavaScript】
日付や時刻を扱う際、軽量で使いやすいJavaScriptライブラリ「Day.js」が便利です。この記事では、Day.jsを使って2つの時刻の差(時間数)を計算する方法を解説します。 時刻データの準備 まず、比較対象となる開始時刻と終了時刻をdayjs()で作成します。ここでは例として、開始時刻を10時、終了時刻を22時に設定します。 var startHour = dayjs().hour(10) var endHour = dayjs().hour(22) diff()メソッドで時刻の差を取得する 2つの時刻の差を求めるには、diff()メソッドを使用します。第1引数に比較対象のDay.js
-
C#で複数のリストの和集合(ユニオン)を求める方法
C#では、LINQのUnionメソッドを使用することで、2つ以上のリストの和集合(ユニオン)を簡単に求めることができます。Unionメソッドは、複数のコレクションを結合しながら、重複する要素を自動的に取り除いた結果を返してくれる便利な機能です。この記事では、3つのリストを例に、Unionメソッドを使って和集合を求める具体的な手順を解説します。1. リストの作成まず、和集合を求める対象となる3つのリストを作成します。//3つのリスト var list1 = new List<int>{3, 4, 5}; var list2 = new List<int>{1, 2, 3,