【发布时间】:2021-03-04 13:21:29
【问题描述】:
我正在尝试用 C++ 和 GLM 模拟牛顿引力。我正在使用 GLM 向量和我在 Wikipedia 上找到的这个等式
我把它翻译成代码:
const static double g_const = 6.67430E-11;
void gravitate(object& obj1,object& obj2) {
glm::vec2 distance = glm::abs(obj2.position-obj1.position);
glm::vec2 unitvec = (obj2.position-obj1.position)/distance;
glm::vec2 force = -g_const*obj1.mass*obj2.mass/(distance*distance)*unitvec;
obj2.updateForce(force);
}
对象类的结构是这样的
class object {
public:
double mass;
glm::vec2 velocity;
glm::vec2 position;
object(double massin, glm::vec2 pos) : mass(massin), position(pos) {;}
object(double massin, glm::vec2 pos, glm::vec2 vel) : mass(massin), position(pos), velocity(vel) {;}
void updateForce(glm::vec2 force) {
velocity+=force/mass;
}
void updatePos() {
position+=velocity;
}
void printPos(); // Not used in this example
void printVel(); // Not used in this example
}
main函数是这样运行的:
int main() {
object test1(massOfEarth,
glm::vec2(0, 0),
glm::vec2(0,0));
object test2(massOfmoon,
glm::vec2(distanceFromEarth,
distanceFromEarth),
moonInitalVelocity);
while (true) {
gravitate(test1,test2);
test2.updatePos();
}
}
但是,当我运行它时,我会得到以下输出:
注意:对于低帧率抱歉,这是将视频转换为 GIF 的副产品
有人知道这里出了什么问题吗?
顺便说一句,完整代码可在此处获得:https://github.com/ProtoByter/GravityLaw
编辑 1:
物体突然加速时施加在物体上的 y 力为 3.5079064080620432e+26 N
当它以恒定速度移动时,y 力为 -2.9308778146655032e+23 N
编辑 2:
为了澄清,我使用牛顿万有引力定律的向量形式,在维基百科上,这被定义为向量,而 glm::distance 返回一个双精度因此不适合
【问题讨论】:
-
有谁知道这里出了什么问题? 也许,物理学专家可以立即看出这里出了什么问题。对于其他傻瓜(比如我),你能解释一下你期望的输出与你得到的相反吗?一般来说,我会使用debugger 来比较程序计算的内容,以将其与“纸上的数字”(即它应该计算的内容)进行比较。
-
我问了我的物理老师,他说我所做的应该有效
-
突然加速是3.5079064080620432e+26 N。因此,在此之前尽可能短地暂停您的程序,然后检查single-step debugging 中的计算。
double的计算并不完全像您在实数的数学/物理课程中学到的那样。它们充其量是相似的,并且仅针对少数几个值(与无限的实数集相比)。对于非常小或非常大的值,您可能会得到奇怪的效果。这是我要搜索的第二个。 -
我的物理老师......说我所做的应该有效:首先我会搜索实现错误。 (我最近刚刚滚动了 doxygen 人。上下滚动,因为我的代码中对组的引用没有按预期工作。最后,我发现我写的是
Progess而不是Progress不知何故这并不容易发现...) -
你除以零。在
gravitate的第 2 行中,当两个对象接近时,distance变为零或接近零。如您所知 lim 1/zero -> 一个巨大的数字。另请注意,您使用的是曼哈顿距离,也许对于您的计算,您应该使用欧几里得距离(在标准 C++ 中计算它的函数称为 hypot,但我不知道您正在使用的库中的等价物)
标签: c++ simulation physics glm-math