I'm currently writing some functions to deal with elastic collisions in C++. I've hit a stumbling block when dealing with a moving object colliding with an immovable object because the calculations require the immovable object to have infinite mass.
I am aware that std::numeric_limits
provides infinity()
but I'm not sure it is entirely useful in this case since, as far as I'm aware, this is just the max number possible in the floating point representation. In the following code, if aabb_obj
has a mass equal to std::numeric_limits<double>::max()
it seems that every calculation that uses it is either going to result in std::numeric_limits<double>::max()
or 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;
}
This is for a game so the results don't need to be 100% physically accurate, just 'good enough'. What is the recommended way for representing infinity in such calculations? Do I just pick an arbitrarily high number?
With IEEE floats, the two infinities are already treated specially by the hardware, along with the Not-A-Number values (NANs). And they obey the normal math rules:
1/0 = +inf
+inf + x = +inf
-inf + +inf = NAN
x/+inf = 0
0*+inf = NAN
...
Now you can check your code to see what happens if you plug in +inf
for one of the masses: This will yield a value of p = 0
, and in the following line p * aabb_obj->mass
will either yield 0
if aabb_obj->mass
is finite, or NAN
if it's infinite. The later case is the one you need to avoid, because the NAN
will be propagated through the other operations, yielding circle_obj->velocity = NAN
.