mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-12 07:10:55 +00:00
added symmetrical absolute/signed windward distance methods on tracked leg and AbstractRankingMetric
This commit is contained in:
1 parent
e4b724142a
commit
470d6fe805
5 files changed
+72
-13
No files matched your search
+37
-8
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ public class OneDesignRankingMetric extends AbstractRankingMetric {
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceSailed() {
|
||||
return getWindwardDistanceTraveled(competitor, timePoint, cache);
|
||||
return getAbsoluteWindwardDistanceTraveled(competitor, timePoint, cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-3
@@ -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();
|
||||
|
||||
}
|
||||
+24
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user