private static (float extraDistance, float percentageAlongRoute) ExtraDistanceIncurred(
            GalacticSystem systemA, GalacticSystem systemB, GalacticPOI poi, float originalDistance)
        {
            var a = systemA.Coordinates;
            var b = systemB.Coordinates;
            var p = poi.Coordinates;

            var aToPOI = System.Numerics.Vector3.Distance(a, p);

            if (a == b)
            {
                return(aToPOI, 0f);
            }

            // Find the closest point to the POI along the straight line route, expressed as 0 (closest to a) to 1 (closest to b).
            float distanceSquared    = originalDistance * originalDistance;
            float distanceAlongRoute = Math.Max(0f, Math.Min(1f, System.Numerics.Vector3.Dot(p - a, b - a) / distanceSquared));

            var bToPOI                     = System.Numerics.Vector3.Distance(b, p);
            var distanceViaPOI             = aToPOI + bToPOI;
            var extraDistance              = distanceViaPOI - originalDistance;
            var approxPercentageAlongRoute = distanceAlongRoute * 100f;

            return(extraDistance, approxPercentageAlongRoute);
        }
        public ScenicSuggestionResults GenerateSuggestions(
            GalacticSystem from,
            GalacticSystem to,
            float acceptableExtraDistance)
        {
            if (DistanceFromSol(to.Coordinates) < bubbleIgnoreRadius && DistanceFromSol(from.Coordinates) < bubbleIgnoreRadius)
            {
                // Warn user that their trip is very close to Earth and we won't have any useful POI suggestions!
                throw new TripWithinBubbleException();
            }
            var originalDistance = DistanceBetweenPoints(from, to);
            var edsmSuggestions  = SuggestionsForList(POIs.Where(p => (int)p.Type < 100));
            var codexSuggestions = SuggestionsForList(POIs.Where(p => (int)p.Type >= 100));

            return(new ScenicSuggestionResults()
            {
                StraightLineDistance = originalDistance,
                Suggestions = edsmSuggestions.Concat(codexSuggestions).ToList()
            });

            List <ScenicSuggestion> SuggestionsForList(IEnumerable <GalacticPOI> pois)
            {
                return(pois.
                       Where(p => p.DistanceFromSol > bubbleIgnoreRadius). // Ignore the "bubble" of near-Earth POIs
                       Select(p =>
                {
                    var result = ExtraDistanceIncurred(@from, to, p, originalDistance);
                    return new ScenicSuggestion(p, result.extraDistance, result.percentageAlongRoute);
                }).
                       Where(ss => ss.ExtraDistance <= acceptableExtraDistance && ss.ExtraDistance > 0f).
                       OrderBy(ss => ss.ExtraDistance).
                       Take(MAX_SUGGESTIONS / 2).
                       ToList());
            }
        }
Exemple #3
0
        public async Task <ScenicSuggestionResults> GenerateSuggestions(
            GalacticSystem from,
            GalacticSystem to,
            float acceptableExtraDistance)
        {
            var calculator = new ScenicSuggestionCalculator(await repository.GetPOIs(), repository.Systems, BUBBLE_IGNORE_RADIUS);

            return(calculator.GenerateSuggestions(from, to, acceptableExtraDistance));
        }