2

現在、C++ でエラスティック コリジョンを処理する関数をいくつか作成しています。動かない物体に衝突する動く物体を扱うとき、つまずきにぶつかりました。これは、計算上、動かない物体の質量が無限である必要があるためです。

提供していることは承知していstd::numeric_limitsますinfinity()が、私が知る限り、これは浮動小数点表現で可能な最大数にすぎないため、この場合に完全に役立つかどうかはわかりません。次のコードでは、 if aabb_objhas mass equal to std::numeric_limits<double>::max()it を使用するすべての計算の結果がstd::numeric_limits<double>::max()またはになるよう0です。

double t;
if (intersect_moving_circle_aabb(circle_obj, aabb_obj, t))
{
    circle_obj->position += circle_obj->velocity * t;

    vec2 closest_point;
    closest_pt_point_aabb(circle_obj->position, aabb_obj, closest_point);

    vec2 n = (closest_point - circle_obj->position).normalized();

    double a = dot_product(circle_obj->velocity, n);

    double p = (2.0 * a) / (circle_obj->mass + aabb_obj->mass);

    circle_obj->velocity = circle_obj->velocity - p * aabb_obj->mass * n;
}

これはゲーム用であるため、結果が 100% 物理的に正確である必要はなく、「十分」である必要があります。そのような計算で無限を表すための推奨される方法は何ですか? 任意に高い数値を選択するだけですか?

4

4 に答える 4

1

問題のコードは、動かない AABB オブジェクトと衝突したときの円形の移動オブジェクトの跳ね返り速度を計算することになっていました。完全に動かないオブジェクトは、理論的には無限の質量を持つはずですが、ご覧のとおり、これを浮動小数点で表すと、計算によって (NaN, NaN) のベクトルが生成されます。

最後に、コードを簡素化する無限質量の明示的なチェックを選択しました。

動かないオブジェクトは衝突から運動量を得ることができず、運動量の保存により、動いているオブジェクトが運動量を失うことはありません。これは、移動するオブジェクトの速度の大きさは変化せず、方向のみが変化するため、両方のオブジェクトの質量は計算に無関係であることを意味します。

これを理解することで、衝突法線に関する速度ベクトルを単純に反映するようにコードを減らすことができました。

double t;
if (aabb_obj->mass == std::numeric_limits<double>::infinity()
    && intersect_moving_circle_aabb(circle_obj, aabb_obj, t))
{
    circle_obj->position += circle_obj->velocity * t;

    vec2 closest_point;
    closest_pt_point_aabb(circle_obj->position, aabb_obj, closest_point);

    vec2 n = (closest_point - circle_obj->position).normalized();

    circle_obj->velocity = circle_obj->velocity - 2.0 * dot_product(circle_obj->velocity, n) * n;
}
于 2016-05-01T15:19:54.770 に答える
0

私の知る限り、これは浮動小数点表現で可能な最大数です。

確かに、IEEE の浮動小数点数は無限大を表すことはできません。それまでの間、これは本当に無限であり、安全に使用できます。

于 2016-04-30T14:39:42.567 に答える