with minor adjustment to test verdict's accuracy requirements, this fixes bug 1952 by using distance to line end if projection outside of line

Change-Id: I76a7f34aaec12040ad457e2cde2da7fee1a1d96d
This commit is contained in:
Axel Uhl committed 2016-12-21 16:22:40 +01:00
1 parent d785e662a0
commit a093541db9
2 files changed
+23 -5

No files matched your search

@@ -90,7 +90,7 @@ public class LineAnalysisTest extends TrackBasedTest {
final Position behindOutsideOfLine = outsideOfLine.translateGreatCircle(awayFromCourseSideOrthogonalToLine, distanceBehindLine);
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindOutsideOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45))));
// the distance is that of the hypotenuse formed by the two cathesuses of 10m and 30m length, respectively:
assertEquals(Math.sqrt(10.*10.+30.*30.), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.000001);
assertEquals(Math.sqrt(10.*10.+30.*30.), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.001);
}
private Mark getMark(String name) {
@@ -3473,10 +3473,28 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
if (secondPosition == null) {
result = null;
} else {
final Bearing bearingGreatCircle = firstPosition.getBearingGreatCircle(secondPosition);
Position competitorProjectedOntoStartLine = competitorPosition.projectToLineThrough(
firstPosition, bearingGreatCircle);
result = competitorPosition.getDistance(competitorProjectedOntoStartLine);
final Bearing lineBearingGreatCircleFromFirstToSecond = firstPosition.getBearingGreatCircle(secondPosition);
// if the competitor is outside of the line when projected orthogonally, compute the distance to
// the nearest of the line's marks (see also bug 1952):
final Bearing bearingFromFirstToCompetitor = firstPosition.getBearingGreatCircle(competitorPosition);
final Bearing angleBetweenFromFirstToCompetitorAndLine = lineBearingGreatCircleFromFirstToSecond.getDifferenceTo(bearingFromFirstToCompetitor);
if (angleBetweenFromFirstToCompetitorAndLine.getDegrees() < -90 || angleBetweenFromFirstToCompetitorAndLine.getDegrees() > 90) {
// competitor's orthogonal projection onto the line's extension is outside of the line's ends on the side
// of the first mark; use distance between competitor and first mark:
result = competitorPosition.getDistance(firstPosition);
} else {
final Bearing bearingFromSecondToCompetitor = secondPosition.getBearingGreatCircle(competitorPosition);
final Bearing angleBetweenFromSecondToCompetitorAndReversedLine = lineBearingGreatCircleFromFirstToSecond.reverse().getDifferenceTo(bearingFromSecondToCompetitor);
if (angleBetweenFromSecondToCompetitorAndReversedLine.getDegrees() < -90 || angleBetweenFromSecondToCompetitorAndReversedLine.getDegrees() > 90) {
// competitor's orthogonal projection onto the line's extension is outside of the line's ends on the side
// of the first mark; use distance between competitor and first mark:
result = competitorPosition.getDistance(secondPosition);
} else {
Position competitorProjectedOntoStartLine = competitorPosition.projectToLineThrough(
firstPosition, lineBearingGreatCircleFromFirstToSecond);
result = competitorPosition.getDistance(competitorProjectedOntoStartLine);
}
}
}
} else {
result = competitorPosition.getDistance(firstPosition);