Problem with calculating potential and kinetic energy
Hello everyone. I need to calculate the mechanical energy of orbiting body , which is a sum of kinetic and potential energy. Mechanical energy should be constant, but for some reason, it isn't.
This is my problem. I don't know why, but the mechanical energy changes, when the object is moving closer/farther from the influencer. I tried calculating everything on double precision numbers, but it didn't work.
public class OrbitingBody : MonoBehaviour {
Rigidbody influencer;
Rigidbody rigidbody;
public float mechanicalEnergy;
public float gravityConstant;
void Start () {
influencer = FindObjectOfType<Influencer>().GetComponent<Rigidbody>();
rigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate () {
mechanicalEnergy = Energy(influencer);
}
float Energy(Rigidbody other)
{
float Ek = rigidbody.mass * rigidbody.velocity.sqrMagnitude / 2; // kinetic energy
float Ep = -gravityConstant * rigidbody.mass * other.mass / (other.transform.position - transform.position).magnitude; // potential energy
return Ek+Ep; // mechanical energy of an object;
}}
}
public class Influencer : MonoBehaviour {
Rigidbody[] rigidbodies;
Rigidbody rigidbody;
public float gravityConstant;
void Start () {
rigidbodies = FindObjectsOfType<Rigidbody>() as Rigidbody[];
rigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
foreach (Rigidbody rigid in rigidbodies)
{
if (rigidbody != rigid)
{
Vector3 dir = rigid.transform.position - transform.position;
rigid.velocity += -dir.normalized * gravityConstant * rigidbody.mass / dir.sqrMagnitude * (Time.fixedDeltaTime);
}
}
}
}
Answer by watah · Feb 14, 2016 at 01:51 AM
I have the same problem with a simple bouncing ball: http://gamebucket.io/game/7817e417-baa5-4e8b-9d54-10457d010770
Here's a better simulation: http://gamebucket.io/game/790591d2-67bc-4a62-acce-097852291fbe
The problem seems to be the way in which the unity 2D physics engine calculates the new position of an object under gravity. It appears that the unity 2D physics engine currently does this:
NewVelocity = OldVelocity + Gravity*DeltaTime
NewPosition = OldPosition + NewVelocity*DeltaTime
However, the correct equation for NewPosition should be
NewPosition = OldPosition + OldVelocity*DeltaTime + (1/2)Gravity(DeltaTime^2)
or, alternatively,
NewPosition = OldPosition + NewVelocity*DeltaTime - (1/2)Gravity(DeltaTime^2)
Since DeltaTime is usually constant, (1/2)Gravity(DeltaTime^2) is usually also constant, and small, but it is a factor that should be taken into account, so that the ball always bounces to height 4 ins$$anonymous$$d of alternating between bouncing to height 4 and height 3.92.
This way the total energy (potential and kinetic) will also be conserved.
Your answer
Follow this Question
Related Questions
Orbit On Rails 1 Answer
How to make an object orbit around another object? 0 Answers