// Cart_2_Geod.java
// to compute the ellipsoidal coordinates from that of Cartesian
public class Cart_2_Geod{
   protected double a;   // semi-major axis of the reference ellipsoid
   protected double ee;   // first eccentricity of the reference ellipsoid
   protected double N;   // the radius of curvature in prime vertical
   public double X, Y, Z;   // Cartesian co-ordinates of a point
   public double Lat, Long;   // Latitude and Longitude of a point
   public double h;   // ellipsoid height of a point

   public Cart_2_Geod( double aa, double e2)
   {
      a = aa;
      ee = e2;
   }
   
   protected double curvature(double lat)
   {
      return a/Math.sqrt(1-ee*Math.pow(Math.sin(lat),2));
   }
   
   public void compute()
   {
      // the problem is that both equations,
      // to determine the ellipsoidal height and latitude, depend on themself!
      // A solution can be found iteratively
      double p;   // the radius of a parallel
      double lat0;   // an approximate value of Latitiude
      
      Long = Math.atan(Y/X);
      p = Math.sqrt( Math.pow(X,2) + Math.pow(Y,2));
      
      // compute an approximate latitude
      Lat = Math.atan(Z / (p*(1-ee)));
      do {
         lat0 = Lat;
         
         // compute an approximate value N
         N = curvature(lat0);
         
         // compute the ellipsoid height
         h = p /Math.cos(lat0) - N;
         
         // compute the improved value for the latitude
         Lat = Math.atan(Z/p/ (1-ee *(N/(N+h))));
      } while (Lat != lat0);
   }
}  // end of Cart_2_Geod.java
