クルマが遠心力でカーブの外側に出ないように適切なバンク角をつける計算。
計算
参考:国土交通省 道路構造令の各規定の解説 III-4.線形
遠心力=質量 * 速度^2 / 曲率半径
Z = (G / g) * (v^2 / R)
Z:遠心力
v:速度(m/s)
g:重力加速度(9.81m/s^2)
G:クルマの総重量(N)
R:曲率半径(m)
f:路面とタイヤの摩擦係数
横滑りを生じさせない条件
ZcosΘ – GsinΘ <= f(ZsinΘ + GcosΘ)
式を変形してΘにまとめる
ZcosΘ – GsinΘ <= fZsinΘ + fGcosΘ
ZcosΘ – fGcosΘ <= fZsinΘ + GsinΘ
cosΘ(Z – fG) <= sinΘ(fZ + G)
(Z – fG) / (fZ + G) <= sinΘ / cosΘ
(Z – fG) / (fZ + G) <= tanΘ
Θ >= atan((Z – fG) / (fZ + G))
Θはatan((Z – fG) / (fZ + G))以上の角度となる。
※1ニュートンは1kgの質量に1m/s^2の加速度を発生させる力(単位:kg・m/s^2)
質量が1トン=1000kgの場合
総重量G = 1000kg * 9.81m/s^2 = 9810N
実装
線形の曲率半径とハーフベクトルを事前に求めておく。ハーフベクトルは遠心力が働く方向の目安として利用する。
//
// 遠心力を計算し、
// ハーフベクトルの長さに掛ける
// RunOver:Points
//
float speed = `chs("../speed")`; // 想定速度(km/h)
float f = `chs("../friction")`; // 摩擦係数
float g = 9.8; // 重力(m/s^2)
float G = 9800; // クルマの重量(N)
// 時速を秒速へ(例:90kmh -> 25m/s)
float v = speed * 1000 / 60 /60;
// 遠心力=速度の二乗÷曲率半径
float Z = v * v / f@__radius * G / g;
// 方勾配の角度を求める
float theta = atan((Z - f*G) / (G + f*Z));
if(theta < 0) theta = 0;
f@__theta = degrees(theta);
// 進行方向の行列
matrix world = maketransform(@N, @up);
matrix inverse = invert(world);
// ハーフベクトルを原点に座標変換し、型勾配のベクトルと比較
vector localH = v@__h * inverse;
vector localLeft = set(cos(theta), sin(theta), 0);
if(localH.x < 0) localLeft.y *= -1;
v@__left = localLeft * world;
@up = cross(@N, v@__left);
UPベクトルはSmooth SOP等で滑らかにする。