Search code examples
c#unity-game-enginegravity

Gravity and Centripetal Force


I am making an application in Unity 3d where I want to code gravity and centripetal force myself but I am getting weird results, am I doing it right? This is my code:

public void Attract(MassObject[] _allMass)
{
    Vector3 F = new Vector3();
    Vector3 C = new Vector3();
    foreach(MassObject i in _allMass)
    {
        // gravity pull
        F.x = GV.gravity * ((mass * i.mass) / (obj.position.x - i.obj.position.x));
        F.y = GV.gravity * ((mass * i.mass) / (obj.position.y - i.obj.position.y));
        F.z = GV.gravity * ((mass * i.mass) / (obj.position.z - i.obj.position.z));

        // centripital force
        C.x = (mass * Mathf.Pow(vel.x,2)) / (obj.position.x - i.obj.position.x);
        C.y = (mass * Mathf.Pow(vel.y,2)) / (obj.position.y - i.obj.position.y);
        C.z = (mass * Mathf.Pow(vel.z,2)) / (obj.position.z - i.obj.position.z);
    }
    vel = F + C;
    Debug.Log(F);
    Debug.Log(C);
}

Solution

  • There are a few problems with this:

    1. You are rewriting F and C with each foreach iteration, so you end up with the for for the last object in the list. You should add all the forces together using += instead of =.

    2. You should be using vector operations rather than manually calculating x y and z. Doing so would make the third error more obvious:

    3. The formula is wrong. For example, this line:

      F.x = GV.gravity * ((mass * i.mass) / (obj.position.x - i.obj.position.x));
      

      with just a few things substituted is

      F.x = gravity coeff * (masses multiplied) / (distance **on the x axis** between objects.)
      

      What you really need is distance between objects, not just on the x axis. You can get this with a vector operation:

      float distanceSquared = (obj.position - i.obj.position).sqrMagnitude;
      

      Then you can use the law of universal gravitation to get the magnitude of the force of gravity:

      float forceMagnitude = GV.gravity * (mass * i.mass) / distanceSquared;
      

      Finally, you need a direction. You can get that with vector subtraction and normalization, then multiplying by the desired magnitude:

      Vector3 force = (i.obj.position - obj.position).normalized * forceMagnitude;
      

      And now force is a vector pointing from obj to i.obj with the magnitude of gravity between the two objects. Add that to F to accumulate the force from each object and things should be good.

    4. Your understanding of physics might be off. If vel is velocity, it is wrong to set it to the sum of two forces. I think you're better off learning about this from somewhere else, though. Understanding Newton's laws is a good start.