56 float yaw = std::numeric_limits<float>::quiet_NaN();
63inline double radians(
double deg) {
return deg * (M_PI / 180.0); }
65inline double constrain(
double v,
double lo,
double hi) {
return std::min(std::max(v, lo), hi); }
95 void project(
double lat,
double lon,
float & x,
float & y)
const
100 const double sinLat = std::sin(latRad);
101 const double cosLat = std::cos(latRad);
102 const double cosDLon = std::cos(lonRad -
refLon_);
106 const double c = std::acos(arg);
109 if (std::fabs(c) > 0.0)
120 void reproject(
float x,
float y,
double & lat,
double & lon)
const
124 const double c = std::sqrt(xRad * xRad + yRad * yRad);
126 if (std::fabs(c) > 0.0)
128 const double sinC = std::sin(c);
129 const double cosC = std::cos(c);
132 const double lonRad =
160 const double dLat = p2 - p1;
163 const double a = std::sin(dLat / 2.0) * std::sin(dLat / 2.0) +
164 std::sin(dLon / 2.0) * std::sin(dLon / 2.0) * std::cos(p1) * std::cos(p2);
165 const double c = 2.0 * std::atan2(std::sqrt(a), std::sqrt(1.0 - a));
182 const double y = std::sin(dLon) * std::cos(p2);
183 const double x = std::cos(p1) * std::sin(p2) - std::sin(p1) * std::cos(p2) * std::cos(dLon);
184 return std::atan2(y, x);
190 const float dx = b.
x - a.
x;
191 const float dy = b.
y - a.
y;
192 const float dz = b.
z - a.
z;
193 return std::sqrt(dx * dx + dy * dy + dz * dz);
198 const float dx = b.
x - a.
x;
199 const float dy = b.
y - a.
y;
200 return std::sqrt(dx * dx + dy * dy);
207 std::vector<float> cum;
208 cum.reserve(path.size());
210 for (
size_t i = 0; i < path.size(); ++i)
214 acc +=
static_cast<double>(
nedDistance(path[i - 1], path[i]));
216 cum.push_back(
static_cast<float>(acc));
234 const std::vector<NedPoint> & path,
const std::vector<float> & cum,
float s,
235 size_t * segmentIndex =
nullptr)
241 if (path.size() == 1 || s <= 0.0f)
243 if (segmentIndex) *segmentIndex = 0;
248 if (segmentIndex) *segmentIndex = path.size() - 2;
253 auto it = std::upper_bound(cum.begin(), cum.end(), s);
254 size_t i1 =
static_cast<size_t>(it - cum.begin());
256 const float segLen = cum[i1] - cum[i0];
257 const float t = segLen > 0.0f ? (s - cum[i0]) / segLen : 0.0f;
259 if (segmentIndex) *segmentIndex = i0;
262 p.
x = path[i0].x + t * (path[i1].x - path[i0].x);
263 p.
y = path[i0].y + t * (path[i1].y - path[i0].y);
264 p.
z = path[i0].z + t * (path[i1].z - path[i0].z);
265 p.
yaw = path[i0].yaw;
271inline std::vector<NedPoint>
resamplePolyline(
const std::vector<NedPoint> & path,
float spacing)
273 std::vector<NedPoint> out;
274 if (path.empty() || spacing <= 0.0f)
278 out.push_back(path.front());
279 for (
size_t i = 1; i < path.size(); ++i)
284 const int n = std::max(1,
static_cast<int>(std::ceil(len / spacing)));
285 for (
int k = 1; k < n; ++k)
287 const float t =
static_cast<float>(k) /
static_cast<float>(n);
289 p.
x = a.
x + t * (b.
x - a.
x);
290 p.
y = a.
y + t * (b.
y - a.
y);
291 p.
z = a.
z + t * (b.
z - a.
z);
void initReference(double lat0, double lon0, uint64_t timestamp=0)
MapProjection(double lat0, double lon0, uint64_t timestamp=0)
double referenceLat() const
bool isInitialized() const
double referenceLon() const
void reproject(float x, float y, double &lat, double &lon) const
uint64_t referenceTimestamp() const
void project(double lat, double lon, float &x, float &y) const
double constrain(double v, double lo, double hi)
double radians(double deg)
double degrees(double rad)
constexpr double kEarthRadiusM
NedPoint sampleAtArcLength(const std::vector< NedPoint > &path, const std::vector< float > &cum, float s, size_t *segmentIndex=nullptr)
float nedDistance(const NedPoint &a, const NedPoint &b)
float polylineLength(const std::vector< NedPoint > &path)
float nedDistanceXY(const NedPoint &a, const NedPoint &b)
std::vector< NedPoint > resamplePolyline(const std::vector< NedPoint > &path, float spacing)
double initialBearing(double lat1, double lon1, double lat2, double lon2)
std::vector< float > cumulativeLengths(const std::vector< NedPoint > &path)
double haversineDistance(double lat1, double lon1, double lat2, double lon2)