c++mathphysicsastronomyorbital-mechanics

Solar System Simulator Physics Integration Issues (Unreal Engine 4, C++)


So I'm making this solar system simulator in Unreal Engine 4 using C++ for a College project, however, I'm new to C++ and UE4 AND I suck at maths so I was in need of a bit of assistance, I wanted to use the Euler integrator for now just to get some basic physics in and have the Moon orbit around the Earth and then move on to probably use the Velocity Verlet method and build the whole Solar System that way. However, as of right now, even the Euler integration doesn't work. Here's the code in Moon.cpp

//Declare the masses
float MMass = 109.456;
float EMass = 1845.833;

//New velocities
float NewMVelX = 0.0;
float NewMVelY = 0.0;
float NewMVelZ = 0.0;

//Distance
float DistanceX = 0.0;
float DistanceY = 0.0;
float DistanceZ = 0.0;

//Earth's velocity
float EVelocityX = 0.0;
float EVelocityY = 0.0;
float EVelocityZ = 0.0;

//Moon's base velocity
float MVelocityX = 0.1;
float MVelocityY = 0.0;
float MVelocityZ = 0.0;

//Moon's acceleration
float MForceX = 0.0;
float MForceY = 0.0;
float MForceZ = 0.0;

//New position
float MPositionX = 0.0;
float MPositionY = 0.0;
float MPositionZ = 0.0;

// Called every frame
void AMoon::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    //Get Earth Location
    FVector EPosition = FVector(0.0, 0.0, 0.0);

    //Get Moon Location
    FVector MPosition = GetActorLocation();

    //Get the distance between the 2 bodies
    DistanceX = (MPosition.X - EPosition.X) / 100;
    DistanceY = (MPosition.Y - EPosition.Y) / 100;
    //DistanceZ = MPosition.Z - EPosition.Z / 100; 


    //Get the acceleration/force for every axis
    MForceX = G * MMass * EMass / (DistanceX * DistanceX);
    MForceY = G * MMass * EMass / (DistanceY * DistanceY);
    //MForceZ = G * MMass * EMass / (DistanceZ * DistanceZ);


    //Get the new velocity
    NewMVelX = MVelocityX + MForceX;
    NewMVelY = MVelocityY + MForceY;
    //NewMVelZ = MVelocityZ + MForceZ * DeltaTime;

    //Get the new location
    MPositionX = (MPosition.X) + NewMVelX;
    MPositionY = (MPosition.Y) + NewMVelY;
    //MPositionZ = MPosition.Z * (MVelocityZ + NewMVelZ) * 0.5 * DeltaTime;

    //Set the new velocity on the old one
    MVelocityX = NewMVelX;
    MVelocityY = NewMVelY;
    //MVelocityZ = NewMVelZ;

    //Assign the new location
    FVector NewMPosition = FVector(MPositionX, MPositionY, MPositionZ);

    //Set the new location
    SetActorLocation(NewMPosition);

}

The values might not be right, I was just making tests at this point. I based this code on the different pieces of information I got on Google and multiple websites but at this point I'm quite confused. What is happening is that the Moon just starts going in 1 direction and never stops. I know my issue is with the force/acceleration/actual gravity of the Earth, it should pull the Moon not push it away. But anyway, if anyone has an idea what I'm doing wrong, I'd be very grateful to hear what you have to say! Thanks


Solution

  • The force depends on the euclidean, rotation-invariant distance. Thus use

    distance = sqrt(distanceX²+distanceY²+distanceZ²)
    
    force = - G*Emass*Mmass/distance²
    
    forceX = force * X/distance
    forceY = force * Y/distance
    forceZ = force * Z/distance
    

    The time stepping of the velocity is also wrong, it should be

    velocityX += forceX/Mmass * deltaTime
    velocityY += forceY/Mmass * deltaTime
    velocityZ += forceZ/Mmass * deltaTime
    

    and of course also the position update contains the time step

    positionX += velocityX * deltaTime
    ....