| 25 | } |
| 26 | |
| 27 | ms::LatLon FromEarth3dToSpherical(m3::PointD const & vec) |
| 28 | { |
| 29 | ASSERT(AlmostEqualAbs(vec.Length(), ms::kEarthRadiusMeters, 1e-5), (vec.Length(), ms::kEarthRadiusMeters)); |
| 30 | |
| 31 | double sinLatRad = vec.z / ms::kEarthRadiusMeters; |
| 32 | sinLatRad = math::Clamp(sinLatRad, -1.0, 1.0); |
| 33 | double const cosLatRad = std::sqrt(1 - sinLatRad * sinLatRad); |
| 34 | CHECK(-1.0 <= cosLatRad && cosLatRad <= 1.0, (cosLatRad)); |
| 35 | |
| 36 | double const latRad = asin(sinLatRad); |
| 37 | double sinLonRad = vec.y / ms::kEarthRadiusMeters / cosLatRad; |
| 38 | sinLonRad = math::Clamp(sinLonRad, -1.0, 1.0); |
| 39 | double lonRad = asin(sinLonRad); |
| 40 | if (vec.y > 0 && vec.x < 0) |
| 41 | lonRad = math::pi - lonRad; |
| 42 | else if (vec.y < 0 && vec.x < 0) |
| 43 | lonRad = -(math::pi - fabs(lonRad)); |
| 44 | |
| 45 | auto const lat = math::RadToDeg(latRad); |
| 46 | auto const lon = math::RadToDeg(lonRad); |
| 47 | |
| 48 | return {lat, lon}; |
| 49 | } |
| 50 | } // namespace |
| 51 | |
| 52 | namespace ms |
no test coverage detected