void OLCTriangle::AddFinishEdges(const ScanTaskPoint origin) { assert(IsFinal(origin.GetStageNumber() + 1)); if (predict) { // dummy just to close the triangle Link(ScanTaskPoint(origin.GetStageNumber() + 1, n_points - 1), origin, 0); } else { const ScanTaskPoint start = FindStart(origin); const TracePoint &start_point = GetPoint(start); const TracePoint &origin_point = GetPoint(origin); const unsigned max_range = trace_master.ProjectRange(origin_point.GetLocation(), max_distance); /* check all remaining points, see which ones match the conditions */ const ScanTaskPoint begin(origin.GetStageNumber() + 1, 0); const ScanTaskPoint end(origin.GetStageNumber() + 1, origin.GetPointIndex()); for (ScanTaskPoint i = begin; i != end; i.IncrementPointIndex()) if (CalcEdgeDistance(start, i) <= max_range && start_point.GetLocation().Distance(GetPoint(i).GetLocation()) < max_distance) Link(i, origin, CalcEdgeDistance(origin, i)); } }
void ContestDijkstra::AddEdges(const ScanTaskPoint origin, const unsigned first_point) { ScanTaskPoint destination(origin.GetStageNumber() + 1, std::max(origin.GetPointIndex(), first_point)); const int min_altitude = IsFinal(destination) ? GetMinimumFinishAltitude(GetPoint(FindStart(origin))) : 0; if (IsFinal(destination) && first_finish_candidate > destination.GetPointIndex()) /* limit the number of finish candidates during incremental search */ destination.SetPointIndex(first_finish_candidate); const unsigned weight = GetStageWeight(origin.GetStageNumber()); bool previous_above = false; for (const ScanTaskPoint end(destination.GetStageNumber(), n_points); destination != end; destination.IncrementPointIndex()) { bool above = GetPoint(destination).GetIntegerAltitude() >= min_altitude; if (above) { const unsigned d = weight * CalcEdgeDistance(origin, destination); Link(destination, origin, d); } else if (previous_above) { /* After excessive thinning, the exact TracePoint that matches the required altitude difference may be gone, and the calculated result becomes overly pessimistic. This code path makes it optimistic, by checking if the previous point matches. */ /* TODO: interpolate the distance */ const unsigned d = weight * CalcEdgeDistance(origin, destination); Link(destination, origin, d); } previous_above = above; } if (IsFinal(destination) && predicted.IsDefined()) { const unsigned d = weight * GetPoint(origin).FlatDistanceTo(predicted); destination.SetPointIndex(predicted_index); Link(destination, origin, d); } }
void ContestDijkstra::AddEdges(const ScanTaskPoint origin, const unsigned first_point) { ScanTaskPoint destination(origin.GetStageNumber() + 1, std::max(origin.GetPointIndex(), first_point)); const int min_altitude = IsFinal(destination) ? GetMinimumFinishAltitude(GetPoint(FindStart(origin))) : 0; if (IsFinal(destination) && first_finish_candidate > destination.GetPointIndex()) /* limit the number of finish candidates during incremental search */ destination.SetPointIndex(first_finish_candidate); const unsigned weight = GetStageWeight(origin.GetStageNumber()); for (const ScanTaskPoint end(destination.GetStageNumber(), n_points); destination != end; destination.IncrementPointIndex()) { if (GetPoint(destination).GetIntegerAltitude() >= min_altitude) { const unsigned d = weight * CalcEdgeDistance(origin, destination); Link(destination, origin, d); } } }
void OLCTriangle::AddEdges(const ScanTaskPoint origin) { assert(origin.GetPointIndex() < n_points); switch (origin.GetStageNumber()) { case 0: // add points up to finish for (ScanTaskPoint destination(origin.GetStageNumber() + 1, 0), end(origin.GetStageNumber() + 1, origin.GetPointIndex()); destination != end; destination.IncrementPointIndex()) { const unsigned d = CalcEdgeDistance(origin, destination); if (!is_fai || 4 * d >= best_d) /* no reason to add candidate if worse than 25% rule for FAI tasks */ Link(destination, origin, GetStageWeight(origin.GetStageNumber()) * d); } break; case 1: { ScanTaskPoint previous = dijkstra.GetPredecessor(origin); // give first leg points to penultimate node TriangleSecondLeg sl(is_fai, GetPoint(previous), GetPoint(origin)); for (ScanTaskPoint destination(origin.GetStageNumber() + 1, origin.GetPointIndex() + 1), end(origin.GetStageNumber() + 1, n_points - 1); destination != end; destination.IncrementPointIndex()) { TriangleSecondLeg::Result result = sl.Calculate(GetPoint(destination), best_d); const unsigned d = result.leg_distance; if (d > 0) { best_d = result.total_distance; Link(destination, origin, GetStageWeight(origin.GetStageNumber()) * d); // we have an improved solution is_complete = true; // need to scan again whether path is closed is_closed = false; first_tp = origin.GetPointIndex(); } } } break; case 2: // dummy just to close the triangle Link(ScanTaskPoint(origin.GetStageNumber() + 1, n_points - 1), origin, 0); break; default: assert(false); } }
void OLCSprint::AddEdges(const ScanTaskPoint origin) { const ScanTaskPoint destination(origin.GetStageNumber() + 1, n_points - 1); if (IsFinal(destination)) { /* For final, only add last valid point */ const unsigned d = GetStageWeight(origin.GetStageNumber()) * CalcEdgeDistance(origin, destination); Link(destination, origin, d); } else ContestDijkstra::AddEdges(origin); }
void OLCTriangle::AddTurn1Edges(const ScanTaskPoint origin) { // add points up to finish const ScanTaskPoint begin(origin.GetStageNumber() + 1, 0); const ScanTaskPoint end(origin.GetStageNumber() + 1, origin.GetPointIndex()); for (ScanTaskPoint i = begin; i != end; i.IncrementPointIndex()) { const unsigned d = CalcEdgeDistance(origin, i); if (!is_fai || 4 * d >= best_d) /* no reason to add candidate if worse than 25% rule for FAI tasks */ Link(i, origin, GetStageWeight(origin.GetStageNumber()) * d); } }