Formulas used in OFP for tide levels and sun and moon positions.

In early October 2002, Ondrej Spanel, BIS' lead programmer, published some snippets of C++ code used in OFP to calculate tide levels and the position of the sun and moon. Here they are, for your reference pleasure:


Tides formula:

const float maxTide=5;
Vector3 sunDir = sun->SunDirection();
Vector3 moonDir = sun->MoonDirection();
Vector3 sunTide = sunDir[1]*sunDir;
Vector3 moonTide = moonDir[1]*moonDir;
float tide01 = (sunTide.Y()+moonTide.Y())*0.5;
float tideAbs =maxTide*tide01;

Note: BIS is aware that the tide formula contains an error. The correct formula should be:

float tide=(fabs(sunTide.Y())+fabs(moonTide.Y())*0.5;

BIS did not correct this,  as it would make many older missions unplayable.


Sun and moon position formula:

float latitudeCoord = world ? world->GetLatitude() : -40*H_PI/180; Matrix3 moonOrbitAngle(MRotationZ,5*H_PI/180);
Matrix3 earthAxis=Matrix3(MRotationX,23*H_PI/180);
Matrix3 latitude(MRotationX,latitudeCoord); // -40 - Croatia, -90 - north pole

const float initMoonOnOrbitPos=0.5;
const float day=1.0/365;
const float lunarMonth=28*day;

float timeInYear = Glob.clock.GetTimeInYear();
float timeOfDay = Glob.clock.GetTimeOfDay();
float moonOnOrbitPos=initMoonOnOrbitPos+timeInYear*(1.0/lunarMonth);
Matrix3 moonOnOrbit=moonOrbitAngle*Matrix3(MRotationY,moonOnOrbitPos*(H_PI*2));
Matrix3 earthOnOrbit=Matrix3(MRotationY,timeInYear*(H_PI*2));
// note - midnight is on the point furthest from the sun Matrix3 midnightToCurrent=Matrix3(MRotationY,timeOfDay*(H_PI*2));
// calculate sun and moon position relative to current postion Matrix3 cameraToCosmos=earthAxis*midnightToCurrent*earthOnOrbit*latitude;
Matrix3 cosmosToCamera=cameraToCosmos.InverseRotation();
// use rotation of PI/2 to achieve this
Matrix3 normalDirection(MRotationX,-H_PI/2);
Matrix3 convert=normalDirection*cosmosToCamera;

// reverse N-S, W-W
_direction[2]=-_direction[2]; _moonDirection[0]=-_moonDirection[0];