万有引力与碰撞

Posted

技术标签:

【中文标题】万有引力与碰撞【英文标题】:Gravitational attraction and collision 【发布时间】:2021-03-18 21:25:02 【问题描述】:

我制作了一个简单的程序来模拟圆形物体在具有重力和碰撞的环境中与圆形表面的行为。

我的问题与重力的应用有关:每当物体非常接近吸引子时,它就会开始重新获得高度,我认为导致问题的原因是,假设球以非常低的速度接触地面,我的程序会应用重力,并且它会接触,反转力并将其再次发送到空中。

一旦球达到足够低的速度,我就尝试停止球,但效果总体上令人不快(它永远不会慢到让它看起来不明显)

这是代码,你认为是什么错误?由于我只列出了部分代码并且它非常复杂,我不希望得到具体的响应,但是您认为问题一般可能在哪里? 我的猜测是我不尊重动能/势能关系,但我也不知道如何使它正确:/

    void update(ArrayList<Attracter>a) 
    pos.add(acceleration);
    println(acceleration.mag());
    for (Attracter ar : a)
      if (PVector.dist(pos, ar.pos)<ar.size/2+size/2)  
        
        //send the compenetrated body back

        float difference=((ar.size/2+size/2)-PVector.dist(pos, ar.pos)+1);
        pos.sub(acceleration.copy().normalize().mult(difference));  
        
        //calculate the new acceleration
        PVector perpendicular= PVector.sub(pos,ar.pos).normalize(); //perpendicolare
        float angle=perpendicular.rotate(-PI/2).heading();//angolo dellatangente
        perpendicular.rotate(-angle); //normalizzo l'angolo
        acceleration.rotate(-angle); //normalizzo l'accellerazione
        
        PVector newAcceleration= PVector.fromAngle(perpendicular.heading()-acceleration.heading());
        acceleration=newAcceleration.setMag(acceleration.mag());
        acceleration.rotate(angle); //denormalizzo l'accellerazione
          
        //push the body forward
        pos.add(acceleration.copy().normalize().mult(difference));
        acceleration.mult(0.9); 
        
  

【问题讨论】:

为什么只使用位置和加速度?速度在哪里?加速度不应直接影响位置。另外,当物体接近吸引子时,它们的速度应该增加,你确定你观察到的行为是错误的吗? 我也不知道每个循环的时间是多少。速度是加速度*时间,加速度是力/质量,力是(G * mass1 * mass2)/距离^2(G是万有引力常数6.673 x 10^-11 N m^2/kg^2)。如果您每秒都在重新计算位置,那么您基本上会应用这些假设距离不会在一秒钟内发生变化,并得到一个错误的近似答案。时间间隔越短,它就会变得越准确。 @Alex 简短的回答是因为我不知道更好,你能把我链接到可以更详细地解释这种分离的东西吗?我也明白,越近的物体力量越大,但是在地球上,球不会像这样无限期地弹跳:streamable.com/llxnpy 这是我试图模仿的。 地球上的球不会因为能量耗散而无限弹跳。有不同的方法来处理这个问题,例如你可以引入一个空气阻力,它是球速度的函数。您也可以在球与地球的每次碰撞中消耗一些能量。这就是你可能试图用最后一行acceleration.mult(0.9); 实现的目标,但你应该用速度操作而不是加速,然后这条线会告诉你,由于能量的耗散,每次碰撞时球的 10% 的速度都会消失。 其实,如果视频是你模拟的结果,那么你的计算可能几乎是正确的,只是变量名称错误,应该叫'velocity',而不是'acceleration'。如果是这种情况,那么您可以尝试引入一些与球的速度成正比的空气阻力。试试这个:作为update 方法的第一行,放入acceleration.mult(Math.exp(-0.1*acceleration.mag()))。您可以尝试使用数值 0.1,增加或减少它,看看它将如何影响您的模拟。 【参考方案1】:

去掉difference calculation中的+1,即尝试替换

float difference=((ar.size/2+size/2)-PVector.dist(pos, ar.pos)+1);

float difference=((ar.size/2+size/2)-PVector.dist(pos, ar.pos));

【讨论】:

以上是关于万有引力与碰撞的主要内容,如果未能解决你的问题,请参考以下文章

碰撞与OnTriggerEnter

16.刚体碰撞事件监测与处理

Unity3d碰撞检测中碰撞器与触发器的区别

使用光线投射和实例化对象问题检查与多边形碰撞器的碰撞(统一)

Unity -- Collider(碰撞器与触发器)

与复杂几何体碰撞和滑动球体