This is part of a game made in Unity3D.
I wrote this class to convert geographic coordinates into lambert 2008 coordinates based on this reference document:
http://www.ngi.be/Common/Lambert2008/Transformation_Geographic_Lambert_FR.pdf
Reason is that I'm using a Belgian National Geographic Institute map as background, and want to locate waypoint and player position with full accuracy.
Code works fine, and runs in .000001s but I'm unhappy with its readability.
I start by declaring all the constants I need
public const int a = 6378137;
public const double f = 1 / 298.257222101;
public const double lowerLatitude = 49.8333333 * Mathf.Deg2Rad;
public const double upperLatitude = 51.1666667 * Mathf.Deg2Rad;
public const double originLatitude = 50.797815 * Mathf.Deg2Rad;
public const double originLongitude = 4.359215833 * Mathf.Deg2Rad;
public const int originX = 649328;
public const int originY = 665262;
Then I used properties for all values derived from those constants
public static double Excentricity {get => System.Math.Sqrt((2 * f) - (f * f));}
static double MLower { get => M(lowerLatitude);}
static double MUpper { get => M(upperLatitude);}
static double M(double latitude)
{
return System.Math.Cos(latitude) / System.Math.Sqrt(1 - (Excentricity * Excentricity * System.Math.Pow(System.Math.Sin(latitude), 2)));
}
static double TLower { get => T(lowerLatitude); }
static double TUpper { get => T(upperLatitude); }
static double TOrigin { get => T(originLatitude); }
static double T(double latitude)
{
return System.Math.Tan(Mathf.PI / 4 - latitude / 2) / System.Math.Pow((1 - Excentricity * System.Math.Sin(latitude)) / (1 + Excentricity * System.Math.Sin(latitude)), Excentricity / 2);
}
static double N { get => (System.Math.Log(MLower) - System.Math.Log(MUpper)) / (System.Math.Log(TLower) - System.Math.Log(TUpper)); }
static double G { get => MLower / (N * System.Math.Pow(TLower, N)); }
static double ROrigin { get => R(TOrigin); }
static double R (double t)
{
return a * G * System.Math.Pow(t, N);
}
As you can see some of the calculations are written on very long lines. I'm unhappy with their readability, but I have no Idea on how to re-write them to make them look better while not messing up floating point approximations.
Finally I perform the actual conversion using all those calculated values.
public static Vector2 FromGeographicRelative(Vector2 coordinates)
{
double t = T((double)coordinates.x * Mathf.Deg2Rad);
double r = R(t);
double angle = N * ((double)coordinates.y * Mathf.Deg2Rad - originLongitude);
Vector2 lambertCoord = new Vector2
{
x = (float) (r * System.Math.Sin(angle)),
y = (float) (ROrigin - r * System.Math.Cos(angle))
};
return lambertCoord;
}