11#include "ns3/angles.h" 
   34auto curvature = [](
double e, 
double ph) { 
return sqrt(1 - e * e * sin(ph) * sin(ph)); };
 
 
   53    double Rn = a / curvature(e, latitudeRadians); 
 
   54    double x = (Rn + altitude) * cos(latitudeRadians) * cos(longitudeRadians);
 
   55    double y = (Rn + altitude) * cos(latitudeRadians) * sin(longitudeRadians);
 
   56    double z = ((1 - e * e) * Rn + altitude) * sin(latitudeRadians);
 
   57    Vector cartesianCoordinates = Vector(x, y, z);
 
   58    return cartesianCoordinates;
 
 
   71    lla.y = atan2(pos.y, pos.x); 
 
   76    lla.x = atan2(pos.z, p * (1 - e2)); 
 
   81        double N = a / sqrt(1 - e2 * sin(tmp.x) * sin(tmp.x));
 
   82        double v = p / cos(tmp.x);
 
   84        lla.x = atan2(pos.z, p * (1 - e2 * N / v));
 
   96        lla.y += lla.y < 0 ? 180 : -180;
 
   98    else if (lla.x < -90.0)
 
  100        lla.x = -180 - lla.x;
 
  101        lla.y += lla.y < 0 ? 180 : -180;
 
  110    NS_ASSERT_MSG(-180.0 <= lla.y, 
"Conversion error: longitude too negative");
 
  111    NS_ASSERT_MSG(180.0 > lla.y, 
"Conversion error: longitude too positive");
 
  112    NS_ASSERT_MSG(-90.0 <= lla.x, 
"Conversion error: latitude too negative");
 
  113    NS_ASSERT_MSG(90.0 >= lla.x, 
"Conversion error: latitude too positive");
 
 
  130    double h0 = refPoint.z;
 
  135    double v = a / curvature(e, phi);
 
  138    double v0 = a / curvature(e, phi0);
 
  140    double U = (v + h) * cos(phi) * sin(lambda - lambda0);
 
  141    double V = (v + h) * (sin(phi) * cos(phi0) - cos(phi) * sin(phi0) * cos(lambda - lambda0)) +
 
  142               e * e * (v0 * sin(phi0) - v * sin(phi)) * cos(phi0);
 
  143    double W = (v + h) * (sin(phi) * sin(phi0) + cos(phi) * cos(phi0) * cos(lambda - lambda0)) +
 
  144               e * e * (v0 * sin(phi0) - v * sin(phi)) * sin(phi0) - (v0 + h0);
 
  146    Vector topocentricCoordinates = Vector(U, V, W);
 
  147    return topocentricCoordinates;
 
 
  162    double h0 = refPoint.z;
 
  168    double v0 = a / curvature(e, phi0);
 
  170    double X0 = (v0 + h0) * cos(phi0) * cos(lambda0);
 
  171    double Y0 = (v0 + h0) * cos(phi0) * sin(lambda0);
 
  172    double Z0 = ((1 - e * e) * v0 + h0) * sin(phi0);
 
  174    double X = X0 - U * sin(lambda0) - V * sin(phi0) * cos(lambda0) + W * cos(phi0) * cos(lambda0);
 
  175    double Y = Y0 + U * cos(lambda0) - V * sin(phi0) * sin(lambda0) + W * cos(phi0) * sin(lambda0);
 
  176    double Z = Z0 + V * cos(phi0) + W * sin(phi0);
 
  178    double epsilon = e * e / (1 - e * e);
 
  179    double b = a * (1 - f);
 
  180    double p = sqrt(X * X + Y * Y);
 
  181    double q = atan2((Z * a), (p * b));
 
  183    double phi = atan2((Z + 
epsilon * b * pow(sin(q), 3)), (p - e * e * a * pow(cos(q), 3)));
 
  184    double lambda = atan2(Y, X);
 
  186    double v = a / curvature(e, phi);
 
  187    double h = (p / cos(phi)) - v;
 
  192    Vector geographicCoordinates = Vector(phi, lambda, h);
 
  193    return geographicCoordinates;
 
 
  198                                                              double originLongitude,
 
  201                                                              double maxDistFromOrigin,
 
  206    if (originLatitude >= 90)
 
  208        NS_LOG_WARN(
"origin latitude must be less than 90. setting to 89.999");
 
  209        originLatitude = 89.999;
 
  211    else if (originLatitude <= -90)
 
  213        NS_LOG_WARN(
"origin latitude must be greater than -90. setting to -89.999");
 
  214        originLatitude = -89.999;
 
  221        NS_LOG_WARN(
"maximum altitude must be greater than or equal to 0. setting to 0");
 
  227    double originColatitude = (M_PI_2)-originLatitudeRadians;
 
  238    std::list<Vector> generatedPoints;
 
  239    for (
int i = 0; i < numPoints; i++)
 
  244        double phi = uniRand->GetValue(0, M_PI * 2);
 
  250        double theta = M_PI_2 - alpha; 
 
  253        double randPointLatitude = asin(sin(theta) * cos(originColatitude) +
 
  254                                        cos(theta) * sin(originColatitude) * sin(phi));
 
  256        double intermedLong = asin((sin(randPointLatitude) * cos(originColatitude) - sin(theta)) /
 
  257                                   (cos(randPointLatitude) * sin(originColatitude)));
 
  259        intermedLong = intermedLong + M_PI_2; 
 
  263        if (phi > (M_PI_2) && phi <= (3 * M_PI_2))
 
  265            intermedLong = -intermedLong;
 
  269        double randPointLongitude = intermedLong + originLongitudeRadians;
 
  272        double randAltitude = uniRand->GetValue(0, maxAltitude);
 
  282        generatedPoints.push_back(pointPosition);
 
  284    return generatedPoints;
 
 
  287std::tuple<double, double, double>
 
  315    return std::make_tuple(a, e, f);
 
 
static std::list< Vector > RandCartesianPointsAroundGeographicPoint(double originLatitude, double originLongitude, double maxAltitude, int numPoints, double maxDistFromOrigin, Ptr< UniformRandomVariable > uniRand)
Generates uniformly distributed random points (in ECEF Cartesian coordinates) within a given altitude...
static constexpr double EARTH_SPHERE_FLATTENING
Earth's flattening if modeled as a perfect sphere.
static constexpr double EARTH_SPHERE_ECCENTRICITY
Earth's eccentricity if modeled as a perfect sphere.
static constexpr double EARTH_SPHERE_RADIUS
Spheroid model to use for earth: perfect sphere (SPHERE), Geodetic Reference System 1980 (GRS80),...
EarthSpheroidType
The possible Earth spheroid models. .
static constexpr double EARTH_GRS80_FLATTENING
Earth's first flattening as defined by GRS80 https://en.wikipedia.org/wiki/Geodetic_Reference_System_...
static constexpr double EARTH_WGS84_ECCENTRICITY
Earth's first eccentricity as defined by https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84.
static Vector TopocentricToGeographicCoordinates(Vector pos, Vector refPoint, EarthSpheroidType sphType)
Conversion from topocentric to geographic.
static Vector GeographicToCartesianCoordinates(double latitude, double longitude, double altitude, EarthSpheroidType sphType)
Converts earth geographic/geodetic coordinates (latitude and longitude in degrees) with a given altit...
static constexpr double EARTH_WGS84_FLATTENING
Earth's first flattening as defined by WGS84 https://en.wikipedia.org/wiki/World_Geodetic_System#WGS8...
static Vector GeographicToTopocentricCoordinates(Vector pos, Vector refPoint, EarthSpheroidType sphType)
Conversion from geographic to topocentric coordinates.
static Vector CartesianToGeographicCoordinates(Vector pos, EarthSpheroidType sphType)
Inverse of GeographicToCartesianCoordinates using [1].
static constexpr double EARTH_SEMIMAJOR_AXIS
<Earth's semi-major axis in meters as defined by both GRS80 and WGS84 https://en.wikipedia....
static std::tuple< double, double, double > GetRadiusEccentFlat(EarthSpheroidType type)
static constexpr double EARTH_GRS80_ECCENTRICITY
Earth's first eccentricity as defined by GRS80 https://en.wikipedia.org/wiki/Geodetic_Reference_Syste...
Smart pointer class similar to boost::intrusive_ptr.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
auto curvature
GRS80 and WGS84 sources.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double DegreesToRadians(double degrees)
converts degrees to radians
double CalculateDistance(const Vector3D &a, const Vector3D &b)
double RadiansToDegrees(double radians)
converts radians to degrees