22#define M_PI 3.14159265358979323846
48 return v == v && v <= DBL_MAX && v >= -DBL_MAX;
65 if (lat < -90.0 || lat > 90.0 || lng < -180.0 || lng > 180.0)
return false;
66 if (lat == 0.0 && lng == 0.0)
return false;
70static inline double geoHaversine(
double lat1,
double lon1,
double lat2,
double lon2) {
71 double lat1Rad = lat1 *
M_PI / 180.0;
72 double lon1Rad = lon1 *
M_PI / 180.0;
73 double lat2Rad = lat2 *
M_PI / 180.0;
74 double lon2Rad = lon2 *
M_PI / 180.0;
76 double sinHalfDLat = sin((lat2Rad - lat1Rad) / 2);
77 double sinHalfDLon = sin((lon2Rad - lon1Rad) / 2);
79 double a = sinHalfDLat * sinHalfDLat + cos(lat1Rad) * cos(lat2Rad) * sinHalfDLon * sinHalfDLon;
80 double c = 2 * atan2(sqrt(a), sqrt(1 - a));
85static inline double geoHaversine3D(
double prevLat,
double prevLng,
double prevAlt,
double currentLat,
double currentLng,
double currentAlt) {
86 double dist =
geoHaversine(prevLat, prevLng, currentLat, currentLng);
87 double altDiff = currentAlt - prevAlt;
88 return sqrt(dist * dist + altDiff * altDiff);
101static inline int geoPointOnSideOfLine(
double driverLat,
double driverLng,
double pointALat,
double pointALng,
double pointBLat,
double pointBLng) {
102 double lineDirectionX = pointBLat - pointALat;
103 double lineDirectionY = pointBLng - pointALng;
104 double driverToPointAX = driverLat - pointALat;
105 double driverToPointAY = driverLng - pointALng;
107 double crossProduct = lineDirectionX * driverToPointAY - lineDirectionY * driverToPointAX;
109 if (crossProduct > 0) {
111 }
else if (crossProduct < 0) {
126 double dx = endX - startX;
127 double dy = endY - startY;
128 double segmentLengthSquared = dx * dx + dy * dy;
131 if (segmentLengthSquared < 1e-12) {
135 double projectionScalar = ((pointX - startX) * dx + (pointY - startY) * dy) / segmentLengthSquared;
137 if (projectionScalar < 0.0) {
139 }
else if (projectionScalar > 1.0) {
143 double projectedX = startX + projectionScalar * dx;
144 double projectedY = startY + projectionScalar * dy;
145 return geoHaversine(pointX, pointY, projectedX, projectedY);
161 double maxLineLength = sqrt(thresholdMeters * thresholdMeters + crossingLineLength * crossingLineLength);
162 return driverLengthA < maxLineLength && driverLengthB < maxLineLength;
static double geoPointLineSegmentDistance(double pointX, double pointY, double startX, double startY, double endX, double endY)
Shortest distance from a point to a line segment, in meters.
Definition GeoMath.h:125
static constexpr double GEOMATH_MPH_TO_KMH
Definition GeoMath.h:34
static constexpr double GEOMATH_KMH_TO_MPH
Definition GeoMath.h:35
static bool geoCoordinatesValid(double lat, double lng)
Validates a GPS coordinate pair before it is allowed to touch timing state.
Definition GeoMath.h:63
static bool geoIsFinite(double v)
Checks a value is a real, finite number (not NaN, not +/-infinity).
Definition GeoMath.h:47
static int geoPointOnSideOfLine(double driverLat, double driverLng, double pointALat, double pointALng, double pointBLat, double pointBLng)
Determines which side of an (infinite) line a point is on.
Definition GeoMath.h:101
static double geoHaversine(double lat1, double lon1, double lat2, double lon2)
Definition GeoMath.h:70
static bool geoInsideLineThreshold(double thresholdMeters, double driverLat, double driverLon, double crossingPointALat, double crossingPointALon, double crossingPointBLat, double crossingPointBLon)
Hypotenuse-based crossing-zone membership test.
Definition GeoMath.h:157
static double geoHaversine3D(double prevLat, double prevLng, double prevAlt, double currentLat, double currentLng, double currentAlt)
Definition GeoMath.h:85
static constexpr double GEOMATH_KNOTS_TO_KMH
Definition GeoMath.h:33
static const double GEOMATH_RADIUS_EARTH
Definition GeoMath.h:25
static constexpr double GEOMATH_METERS_TO_FEET
Definition GeoMath.h:36
#define M_PI
Definition GeoMath.h:22
const double crossingPointBLat
Definition basic_oled_example.ino:21
const double crossingPointALat
Definition basic_oled_example.ino:19