在物理计算中表示无穷大
Representing infinity in physics calculations
我目前正在编写一些函数来处理C++中的弹性碰撞。在处理移动物体与不可移动物体碰撞时,我遇到了绊脚石,因为计算要求不可移动物体具有无限的质量。
我知道std::numeric_limits
提供了infinity()
但我不确定它在这种情况下是否完全有用,因为据我所知,这只是浮点表示中可能的最大数量。在下面的代码中,如果aabb_obj
的质量等于 std::numeric_limits<double>::max()
似乎使用它的每个计算都会导致 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% 物理准确,只需"足够好"。在此类计算中表示无穷大的推荐方法是什么?我只是选择一个任意高的数字吗?
对于 IEEE 浮点数,硬件已经对两个无穷大以及非数字值 (NAN( 进行了特殊处理。他们遵守正常的数学规则:
1/0 = +inf
+inf + x = +inf
-inf + +inf = NAN
x/+inf = 0
0*+inf = NAN
...
现在,您可以检查代码,看看如果为其中一个质量块插入+inf
会发生什么情况: 这将产生 p = 0
的值,在下一行中,如果aabb_obj->mass
是有限的,则p * aabb_obj->mass
将产生0
,如果它是无限的,则NAN
。后一种情况是您需要避免的情况,因为NAN
将通过其他操作传播,从而产生circle_obj->velocity = NAN
。
是你,我会在我的代码中明确某些对象是不移动的事实。例如,与其将值代入一个应防止某些对象移动的通用公式中,不如对两个可移动对象碰撞与可移动和不可移动对象碰撞具有不同的执行分支。
此外,如果准确性不是一个大问题,请使用 float
s 而不是 double
s:)。
问题中的代码应该计算圆形运动物体与不可移动的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;
}
据我所知,这只是浮点表示中可能的最大数量。
当然是这样,因为IEEE浮点数不能代表大于无穷大的任何内容。同时,这确实是无限的,您可以安全地使用它。
- 表示"accepting anything for this template argument" C++概念的通配符
- 如何将ampl中的集合表示为c++中的向量
- std::is_base_of表示ctor编译错误
- 输入中的字符串数未知(以字母表示)
- 我可以信任表示整数的浮点或双精度来保持精度吗
- c++模板来表示多项式
- 询问在设计我的手臂模拟器功能表示格式1
- CMakeLists.txt中的命名空间表示法
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 如何计算Big-O表示法中的平均渐近运行时间
- 我应该如何表示我拥有的连续元素序列?
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 表示类模板C++空类型
- 具有所表示类的相同构造函数签名的代理类模板
- 嵌套在循环中的两个循环的 big-O 表示法
- 具有引用成员的结构是否具有唯一的对象表示形式
- 如何获得从负无穷大到无穷大的范围以在 0 到 1 的范围内表示
- 在物理计算中表示无穷大
- C++ NTL(Victor Shoup著):如何表示无穷大