Fixed perpendicular distance calculation of segment endpoint is on equator
This commit is contained in:
parent
2a6585e664
commit
b453a42f77
@ -159,10 +159,10 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
|
|||||||
// initialize values
|
// initialize values
|
||||||
const float x_value = lat2y(point.lat / COORDINATE_PRECISION);
|
const float x_value = lat2y(point.lat / COORDINATE_PRECISION);
|
||||||
const float y_value = point.lon / COORDINATE_PRECISION;
|
const float y_value = point.lon / COORDINATE_PRECISION;
|
||||||
const float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION);
|
float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION);
|
||||||
const float b = source_coordinate.lon / COORDINATE_PRECISION;
|
float b = source_coordinate.lon / COORDINATE_PRECISION;
|
||||||
const float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION);
|
float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION);
|
||||||
const float d = target_coordinate.lon / COORDINATE_PRECISION;
|
float d = target_coordinate.lon / COORDINATE_PRECISION;
|
||||||
float p, q;
|
float p, q;
|
||||||
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
|
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
|
||||||
{
|
{
|
||||||
@ -178,15 +178,35 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
|
|||||||
q = y_value;
|
q = y_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float nY = (d * p - c * q) / (a * d - b * c);
|
float ratio;
|
||||||
// discretize the result to coordinate precision. it's a hack!
|
bool inverse_ratio = false;
|
||||||
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
|
|
||||||
|
// straight line segment on equator
|
||||||
|
if (std::abs(c) < std::numeric_limits<float>::epsilon() && std::abs(a) < std::numeric_limits<float>::epsilon())
|
||||||
{
|
{
|
||||||
nY = 0.f;
|
ratio = (q - b) / (d - b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (std::abs(c) < std::numeric_limits<float>::epsilon())
|
||||||
|
{
|
||||||
|
// swap start/end
|
||||||
|
std::swap(a, c);
|
||||||
|
std::swap(b, d);
|
||||||
|
inverse_ratio = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float nY = (d * p - c * q) / (a * d - b * c);
|
||||||
|
// discretize the result to coordinate precision. it's a hack!
|
||||||
|
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
|
||||||
|
{
|
||||||
|
nY = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute ratio
|
||||||
|
ratio = (p - nY * a) / c;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute ratio
|
|
||||||
float ratio = (p - nY * a) / c;
|
|
||||||
if (std::isnan(ratio))
|
if (std::isnan(ratio))
|
||||||
{
|
{
|
||||||
ratio = (target_coordinate == point ? 1.f : 0.f);
|
ratio = (target_coordinate == point ? 1.f : 0.f);
|
||||||
@ -200,6 +220,12 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
|
|||||||
ratio = 1.f;
|
ratio = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we need to do this, if we switched start/end coordinates
|
||||||
|
if (inverse_ratio)
|
||||||
|
{
|
||||||
|
ratio = 1.0f - ratio;
|
||||||
|
}
|
||||||
|
|
||||||
//compute the nearest location
|
//compute the nearest location
|
||||||
FixedPointCoordinate nearest_location;
|
FixedPointCoordinate nearest_location;
|
||||||
BOOST_ASSERT(!std::isnan(ratio));
|
BOOST_ASSERT(!std::isnan(ratio));
|
||||||
@ -216,6 +242,7 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
|
|||||||
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
|
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
|
||||||
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
|
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_ASSERT(nearest_location.isValid());
|
BOOST_ASSERT(nearest_location.isValid());
|
||||||
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
|
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user