added symmetrical absolute/signed windward distance methods on tracked leg and AbstractRankingMetric

This commit is contained in:
Axel Uhl committed 2015-05-18 18:40:05 +02:00
1 parent e4b724142a
commit 470d6fe805
5 files changed
+72 -13

No files matched your search

@@ -210,11 +210,11 @@ public abstract class AbstractRankingMetric implements RankingMetric {
public RankingMetric.RankingInfo getRankingInfo(TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
Map<Competitor, RankingMetric.CompetitorRankingInfo> result = new HashMap<>();
RaceRankComparator oneDesignComparator = new RaceRankComparator(getTrackedRace(), timePoint, new LeaderboardDTOCalculationReuseCache(timePoint));
RaceRankComparator oneDesignComparator = new RaceRankComparator(getTrackedRace(), timePoint, cache);
Competitor competitorFarthestAhead = StreamSupport
.stream(getTrackedRace().getRace().getCompetitors().spliterator(), /* parallel */true).
sorted(oneDesignComparator).findFirst().get();
final Distance totalWindwardDistanceTraveled = getWindwardDistanceTraveled(competitorFarthestAhead, timePoint, cache);
final Distance totalWindwardDistanceTraveled = getAbsoluteWindwardDistanceTraveled(competitorFarthestAhead, timePoint, cache);
final TimePoint startOfRace = getTrackedRace().getStartOfRace();
final Duration actualRaceDuration;
if (startOfRace == null) {
@@ -239,7 +239,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
.getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolated */true),
actualRaceDuration, totalWindwardDistanceTraveled);
RankingMetric.CompetitorRankingInfo rankingInfo = new CompetitorRankingInfoImpl(timePoint, competitor,
getWindwardDistanceTraveled(competitor, timePoint, cache), actualRaceDuration, correctedTime,
getAbsoluteWindwardDistanceTraveled(competitor, timePoint, cache), actualRaceDuration, correctedTime,
predictedDurationToReachWindwardPositionOfCompetitorFarthestAhead,
correctedEstimatedTimeWhenReachingCompetitorFarthestAhead);
result.put(competitor, rankingInfo);
@@ -286,7 +286,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
* current leg is estimated using
* {@link TrackedLegOfCompetitor#getEstimatedTimeToNextMark(TimePoint, com.sap.sailing.domain.tracking.WindPositionMode)}
* ; then from the waypoint reached this way the
* {@link #getWindwardDistanceTraveled(Competitor, Waypoint, TimePoint) windward distance to competitor
* {@link #getAbsoluteWindwardDistanceTraveled(Competitor, Waypoint, TimePoint) windward distance to competitor
* <code>to</code>} is determined and from this, using the handicaps for both competitors, <code>who</code> and
* <code>to</code>, their performance between the waypoint and <code>to</code>'s position at <code>timePoint</code>
* is equated, hence assuming that considering their handicaps, both competitors are doing equally well on this part
@@ -339,7 +339,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
*/
protected Duration getPredictedDurationToEndOfLegOrTo(Competitor who, Competitor to, TimePoint timePoint,
final TrackedLegOfCompetitor currentLegWho, final TrackedLegOfCompetitor currentLegTo, WindLegTypeAndLegBearingCache cache) {
assert getWindwardDistanceTraveled(to, timePoint, cache).compareTo(getWindwardDistanceTraveled(who, timePoint, cache)) >= 0;
assert getAbsoluteWindwardDistanceTraveled(to, timePoint, cache).compareTo(getAbsoluteWindwardDistanceTraveled(who, timePoint, cache)) >= 0;
final Position windwardPositionToReachInWhosCurrentLeg =
(currentLegWho.getLeg() == currentLegTo.getLeg())
// both are currently in the same leg; estimate who's arrival at to's current windward position
@@ -382,10 +382,39 @@ public abstract class AbstractRankingMetric implements RankingMetric {
}
}
protected Distance getAbsoluteWindwardDistanceTraveled(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
return getAbsoluteWindwardDistanceTraveled(competitor, getTrackedRace().getRace().getCourse().getFirstWaypoint(), timePoint, cache);
}
protected Distance getWindwardDistanceTraveled(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
return getWindwardDistanceTraveled(competitor, getTrackedRace().getRace().getCourse().getFirstWaypoint(), timePoint, cache);
}
protected Distance getWindwardDistanceTraveled(Competitor competitor, Waypoint from, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
TrackedLegOfCompetitor currentLeg = getTrackedRace().getCurrentLeg(competitor, timePoint);
final Distance result;
if (currentLeg == null || from == null) {
result = null;
} else {
Distance d = Distance.NULL;
boolean count = false; // start counting only once the "from" waypoint has been found
for (TrackedLeg trackedLeg : getTrackedRace().getTrackedLegs()) {
count = count || trackedLeg.getLeg().getFrom() == from;
if (count) {
if (trackedLeg.getLeg() == currentLeg.getLeg()) {
// partial distance sailed:
d = d.add(trackedLeg.getWindwardDistanceFromLegStart(getTrackedRace().getTrack(competitor)
.getEstimatedPosition(timePoint, /* extrapolate */true), cache));
break;
} else {
d = d.add(trackedLeg.getWindwardDistance(cache));
}
}
}
result = d;
}
return result;
}
/**
* How far did <code>competitor</code> sail windwards/along-course since passing the <code>from</code> waypoint?
*
@@ -393,7 +422,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
* time point for wind approximation is taken to be a reference time point selected based on the mark passings
* for the respective leg's from/to waypoints.
*/
protected Distance getWindwardDistanceTraveled(Competitor competitor, Waypoint from, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
protected Distance getAbsoluteWindwardDistanceTraveled(Competitor competitor, Waypoint from, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
TrackedLegOfCompetitor currentLeg = getTrackedRace().getCurrentLeg(competitor, timePoint);
final Distance result;
if (currentLeg == null || from == null) {
@@ -410,7 +439,7 @@ public abstract class AbstractRankingMetric implements RankingMetric {
.getEstimatedPosition(timePoint, /* extrapolate */true), cache));
break;
} else {
d = d.add(trackedLeg.getWindwardDistance());
d = d.add(trackedLeg.getAbsoluteWindwardDistance(cache));
}
}
}
@@ -97,7 +97,7 @@ public class OneDesignRankingMetric extends AbstractRankingMetric {
@Override
public Distance getWindwardDistanceSailed() {
return getWindwardDistanceTraveled(competitor, timePoint, cache);
return getAbsoluteWindwardDistanceTraveled(competitor, timePoint, cache);
}
@Override
@@ -133,7 +133,7 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
} else {
positionOfFastestBoatInLegAtTimePointOrLegEnd = getTrackedRace().getTrack(fastestCompetitorInLeg)
.getEstimatedPosition(timePoint, /* extrapolate */true);
totalWindwardDistanceLegLeaderTraveledUpToTimePointOrLegEnd = getWindwardDistanceTraveled(
totalWindwardDistanceLegLeaderTraveledUpToTimePointOrLegEnd = getAbsoluteWindwardDistanceTraveled(
fastestCompetitorInLeg, timePoint, cache);
}
for (Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
@@ -203,7 +203,7 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
@Override
public Duration getCorrectedTime(Competitor competitor, TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
final Duration timeActuallySpent = getActualTimeSinceStartOfRace(competitor, timePoint);
final Distance windwardDistanceSailed = getWindwardDistanceTraveled(competitor, timePoint, cache);
final Distance windwardDistanceSailed = getAbsoluteWindwardDistanceTraveled(competitor, timePoint, cache);
return getCorrectedTime(competitor, ()->getTrackedRace().getCurrentLeg(competitor, timePoint).getLeg(),
()->getTrackedRace().getTrack(competitor).getEstimatedPosition(timePoint, /* extrapolate */true),
timeActuallySpent, windwardDistanceSailed);
@@ -240,7 +240,7 @@ public class TimeOnTimeAndDistanceRankingMetric extends AbstractRankingMetric {
final MarkPassing whenToPassedFromWaypoint = getTrackedRace().getMarkPassing(to, fromWaypoint);
validateGetDurationToReachAtEqualPerformanceParameters(to, fromWaypoint, timePointOfTosPosition, whenToPassedFromWaypoint);
final Duration t_to = whenToPassedFromWaypoint.getTimePoint().until(timePointOfTosPosition);
final Distance d_to = getWindwardDistanceTraveled(to, fromWaypoint, timePointOfTosPosition, cache);
final Distance d_to = getAbsoluteWindwardDistanceTraveled(to, fromWaypoint, timePointOfTosPosition, cache);
final double f_to = getTimeOnTimeFactor(to);
final Duration timeOnDistanceFactorInSecondsPerNauticalMileTo = getTimeOnDistanceFactorInSecondsPerNauticalMile(to);
final double g_to = timeOnDistanceFactorInSecondsPerNauticalMileTo==null?0:timeOnDistanceFactorInSecondsPerNauticalMileTo.asSeconds();
@@ -109,10 +109,11 @@ public interface TrackedLeg extends Serializable {
* Computes the windward distance for upwind/downwind legs or the great circle distance between this leg's waypoints
* that competitors need to travel in this leg. Due to the dynamics of the wind direction and the mark positions,
* the result is time dependent. The wind direction is determined at the leg's middle at the time point <code>at</code>.
* @param cache TODO
*/
Distance getWindwardDistance(TimePoint at, WindLegTypeAndLegBearingCache cache);
Distance getAbsoluteWindwardDistance(TimePoint at, WindLegTypeAndLegBearingCache cache);
/**
* Computes the windward distance for upwind/downwind legs or the great circle distance between this leg's waypoints
* that competitors need to travel in this leg. Due to the dynamics of the wind direction and the mark positions,
@@ -128,6 +129,8 @@ public interface TrackedLeg extends Serializable {
*/
Distance getWindwardDistance(WindLegTypeAndLegBearingCache cache);
Distance getAbsoluteWindwardDistance(WindLegTypeAndLegBearingCache cache);
/**
* The middle (traveling half the length) of the course middle line, connecting the center of gravity of the leg's start
* waypoint's position at time point <code>at</code> and the position of the leg's end waypoint at time point <code>at</code>.
@@ -155,6 +158,8 @@ public interface TrackedLeg extends Serializable {
*/
Distance getAbsoluteWindwardDistanceFromLegStart(Position pos, WindLegTypeAndLegBearingCache cache);
Distance getWindwardDistanceFromLegStart(Position pos, WindLegTypeAndLegBearingCache cache);
/**
* Determines an average true wind direction for this leg; it does so by querying the tracked race for
* wind data at the leg's middle around a reference time point which is defined by the mark passings
@@ -169,4 +174,5 @@ public interface TrackedLeg extends Serializable {
* "now" is used.
*/
TimePoint getReferenceTimePoint();
}
@@ -356,6 +356,17 @@ public class TrackedLegImpl implements TrackedLeg {
return getAbsoluteWindwardDistanceFromLegStart(pos, referenceTimePoint, new LeaderboardDTOCalculationReuseCache(referenceTimePoint));
}
@Override
public Distance getWindwardDistanceFromLegStart(Position pos, WindLegTypeAndLegBearingCache cache) {
final TimePoint referenceTimePoint = getReferenceTimePoint();
return getWindwardDistanceFromLegStart(pos, referenceTimePoint, cache);
}
private Distance getWindwardDistanceFromLegStart(Position pos, final TimePoint timePoint, WindLegTypeAndLegBearingCache cache) {
return getWindwardDistance(getTrackedRace().getApproximatePosition(getLeg().getFrom(), timePoint),
pos, timePoint, WindPositionMode.LEG_MIDDLE, cache);
}
@Override
public Distance getAbsoluteWindwardDistanceFromLegStart(Position pos, WindLegTypeAndLegBearingCache cache) {
final TimePoint referenceTimePoint = getReferenceTimePoint();
@@ -387,6 +398,12 @@ public class TrackedLegImpl implements TrackedLeg {
return getWindwardDistance(middle, cache);
}
@Override
public Distance getAbsoluteWindwardDistance(WindLegTypeAndLegBearingCache cache) {
final TimePoint middle = getReferenceTimePoint();
return getAbsoluteWindwardDistance(middle, cache);
}
@Override
public TimePoint getReferenceTimePoint() {
Iterable<MarkPassing> legStartMarkPassings = getTrackedRace().getMarkPassingsInOrder(getLeg().getFrom());
@@ -426,6 +443,13 @@ public class TrackedLegImpl implements TrackedLeg {
return getWindwardDistance(fromPos, toPos, middle, WindPositionMode.LEG_MIDDLE, cache);
}
@Override
public Distance getAbsoluteWindwardDistance(final TimePoint middle, WindLegTypeAndLegBearingCache cache) {
final Position fromPos = getTrackedRace().getApproximatePosition(getLeg().getFrom(), middle);
final Position toPos = getTrackedRace().getApproximatePosition(getLeg().getTo(), middle);
return getAbsoluteWindwardDistance(fromPos, toPos, middle, WindPositionMode.LEG_MIDDLE, cache);
}
Distance getWindwardDistance(final Position pos1, final Position pos2, TimePoint at, WindPositionMode windPositionMode, WindLegTypeAndLegBearingCache cache) {
Distance result;
try {