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
 | ||||
|     const float x_value = lat2y(point.lat / COORDINATE_PRECISION); | ||||
|     const float y_value = point.lon / COORDINATE_PRECISION; | ||||
|     const float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION); | ||||
|     const float b = source_coordinate.lon / COORDINATE_PRECISION; | ||||
|     const float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION); | ||||
|     const float d = target_coordinate.lon / COORDINATE_PRECISION; | ||||
|     float a = lat2y(source_coordinate.lat / COORDINATE_PRECISION); | ||||
|     float b = source_coordinate.lon / COORDINATE_PRECISION; | ||||
|     float c = lat2y(target_coordinate.lat / COORDINATE_PRECISION); | ||||
|     float d = target_coordinate.lon / COORDINATE_PRECISION; | ||||
|     float p, q; | ||||
|     if (std::abs(a - c) > std::numeric_limits<float>::epsilon()) | ||||
|     { | ||||
| @ -178,6 +178,24 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s | ||||
|         q = y_value; | ||||
|     } | ||||
| 
 | ||||
|     float ratio; | ||||
|     bool inverse_ratio = false; | ||||
| 
 | ||||
|     // straight line segment on equator
 | ||||
|     if (std::abs(c) < std::numeric_limits<float>::epsilon() && std::abs(a) < std::numeric_limits<float>::epsilon()) | ||||
|     { | ||||
|         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)) | ||||
| @ -186,7 +204,9 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s | ||||
|         } | ||||
| 
 | ||||
|         // compute ratio
 | ||||
|     float ratio = (p - nY * a) / c; | ||||
|         ratio = (p - nY * a) / c; | ||||
|     } | ||||
| 
 | ||||
|     if (std::isnan(ratio)) | ||||
|     { | ||||
|         ratio = (target_coordinate == point ? 1.f : 0.f); | ||||
| @ -200,6 +220,12 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s | ||||
|         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
 | ||||
|     FixedPointCoordinate nearest_location; | ||||
|     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.lon = static_cast<int>(q * COORDINATE_PRECISION); | ||||
|     } | ||||
| 
 | ||||
|     BOOST_ASSERT(nearest_location.isValid()); | ||||
|     return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user