Esempio n. 1
0
        /// <summary>Constructs a link between two satellites, if one is possible.</summary>
        /// <returns>The new link, or null if the two satellites cannot connect.</returns>
        /// <param name="rangeFunc">A function that computes the maximum range between two
        /// satellites, given their individual ranges.</param>
        public static NetworkLink <ISatellite> GetLink(ISatellite satA, ISatellite satB,
                                                       Func <double, double, double> rangeFunc)
        {
            // Which antennas on either craft are capable of communication?
            IEnumerable <IAntenna> omnisA  = GetOmnis(satA);
            IEnumerable <IAntenna> omnisB  = GetOmnis(satB);
            IEnumerable <IAntenna> dishesA = GetDishesThatSee(satA, satB);
            IEnumerable <IAntenna> dishesB = GetDishesThatSee(satB, satA);

            // Pick the best range for each case
            double maxOmniA = omnisA.Any() ?  omnisA.Max(ant => ant.Omni) : 0.0;
            double maxOmniB = omnisB.Any() ?  omnisB.Max(ant => ant.Omni) : 0.0;
            double maxDishA = dishesA.Any() ? dishesA.Max(ant => ant.Dish) : 0.0;
            double maxDishB = dishesB.Any() ? dishesB.Max(ant => ant.Dish) : 0.0;

            double bonusA = GetMultipleAntennaBonus(omnisA, maxOmniA);
            double bonusB = GetMultipleAntennaBonus(omnisB, maxOmniB);

            double distance = satA.DistanceTo(satB);

            // Which antennas have the range to reach at least one antenna on the other satellite??
            omnisA = omnisA.Where(ant =>
                                  CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxOmniB + bonusB, omniClamp) >= distance ||
                                  CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxDishB, dishClamp) >= distance);
            dishesA = dishesA.Where(ant =>
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxOmniB + bonusB, omniClamp) >= distance ||
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxDishB, dishClamp) >= distance);
            omnisB = omnisB.Where(ant =>
                                  CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxOmniA + bonusA, omniClamp) >= distance ||
                                  CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxDishA, dishClamp) >= distance);
            dishesB = dishesB.Where(ant =>
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxOmniA + bonusA, omniClamp) >= distance ||
                                    CheckRange(rangeFunc, ant.Dish, dishClamp, maxDishA, dishClamp) >= distance);

            // Just because an antenna is in `omnisA.Concat(dishesA)` doesn't mean it can connect to *any*
            //  antenna in `omnisB.Concat(dishesB)`, and vice versa. Pick the max to be safe.
            IAntenna selectedAntennaA = omnisA.Concat(dishesA)
                                        .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();
            IAntenna selectedAntennaB = omnisB.Concat(dishesB)
                                        .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();

            if (selectedAntennaA != null && selectedAntennaB != null)
            {
                List <IAntenna> interfaces = omnisA.Concat(dishesA).ToList();

                LinkType type = (dishesA.Contains(selectedAntennaA) || dishesB.Contains(selectedAntennaB)
                    ? LinkType.Dish : LinkType.Omni);

                return(new NetworkLink <ISatellite>(satB, interfaces, type));
            }

            return(null);
        }
Esempio n. 2
0
        /// <summary>Constructs a link between two satellites, if one is possible.</summary>
        /// <returns>The new link, or null if the two satellites cannot connect.</returns>
        /// <param name="rangeFunc">A function that computes the maximum range between two 
        /// satellites, given their individual ranges.</param>
        public static NetworkLink<ISatellite> GetLink(ISatellite satA, ISatellite satB, 
            Func<double, double, double> rangeFunc) {
            // Which antennas on either craft are capable of communication?
            IEnumerable<IAntenna>  omnisA = GetOmnis(satA);
            IEnumerable<IAntenna>  omnisB = GetOmnis(satB);
            IEnumerable<IAntenna> dishesA = GetDishesThatSee(satA, satB);
            IEnumerable<IAntenna> dishesB = GetDishesThatSee(satB, satA);

            // Pick the best range for each case
            double maxOmniA =  omnisA.Any() ?  omnisA.Max(ant => ant.Omni) : 0.0;
            double maxOmniB =  omnisB.Any() ?  omnisB.Max(ant => ant.Omni) : 0.0;
            double maxDishA = dishesA.Any() ? dishesA.Max(ant => ant.Dish) : 0.0;
            double maxDishB = dishesB.Any() ? dishesB.Max(ant => ant.Dish) : 0.0;

            double bonusA = GetMultipleAntennaBonus(omnisA, maxOmniA);
            double bonusB = GetMultipleAntennaBonus(omnisB, maxOmniB);

            double distance = satA.DistanceTo(satB);

            // Which antennas have the range to reach at least one antenna on the other satellite??
            omnisA = omnisA.Where(ant => 
                   CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxOmniB + bonusB, omniClamp) >= distance
                || CheckRange(rangeFunc, ant.Omni + bonusA, omniClamp, maxDishB         , dishClamp) >= distance);
            dishesA = dishesA.Where(ant => 
                   CheckRange(rangeFunc, ant.Dish         , dishClamp, maxOmniB + bonusB, omniClamp) >= distance 
                || CheckRange(rangeFunc, ant.Dish         , dishClamp, maxDishB         , dishClamp) >= distance);
            omnisB = omnisB.Where(ant => 
                   CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxOmniA + bonusA, omniClamp) >= distance
                || CheckRange(rangeFunc, ant.Omni + bonusB, omniClamp, maxDishA         , dishClamp) >= distance);
            dishesB = dishesB.Where(ant => 
                   CheckRange(rangeFunc, ant.Dish         , dishClamp, maxOmniA + bonusA, omniClamp) >= distance 
                || CheckRange(rangeFunc, ant.Dish         , dishClamp, maxDishA         , dishClamp) >= distance);

            // Just because an antenna is in `omnisA.Concat(dishesA)` doesn't mean it can connect to *any*
            //  antenna in `omnisB.Concat(dishesB)`, and vice versa. Pick the max to be safe.
            IAntenna selectedAntennaA = omnisA.Concat(dishesA)
                .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();
            IAntenna selectedAntennaB = omnisB.Concat(dishesB)
                .OrderByDescending(ant => Math.Max(ant.Omni, ant.Dish)).FirstOrDefault();

            if (selectedAntennaA != null && selectedAntennaB != null)
            {
                List<IAntenna> interfaces = omnisA.Concat(dishesA).ToList();

                LinkType type = (dishesA.Contains(selectedAntennaA) || dishesB.Contains(selectedAntennaB) 
                    ? LinkType.Dish : LinkType.Omni);

                return new NetworkLink<ISatellite>(satB, interfaces, type);
            }

            return null;
        }
Esempio n. 3
0
        public static NetworkLink <ISatellite> GetLink(ISatellite sat_a, ISatellite sat_b)
        {
            var omni_a = sat_a.Antennas.Where(a => a.Omni > 0);
            var omni_b = sat_b.Antennas.Where(b => b.Omni > 0);
            var dish_a = sat_a.Antennas.Where(a => a.Dish > 0 && (a.IsTargetingDirectly(sat_b) || a.IsTargetingActiveVessel(sat_b) || a.IsTargetingPlanet(sat_b, sat_a)));
            var dish_b = sat_b.Antennas.Where(b => b.Dish > 0 && (b.IsTargetingDirectly(sat_a) || b.IsTargetingActiveVessel(sat_a) || b.IsTargetingPlanet(sat_a, sat_b)));

            double max_omni_a = omni_a.Any() ? omni_a.Max(a => a.Omni) : 0.0;
            double max_omni_b = omni_b.Any() ? omni_b.Max(b => b.Omni) : 0.0;
            double max_dish_a = dish_a.Any() ? dish_a.Max(a => a.Dish) : 0.0;
            double max_dish_b = dish_b.Any() ? dish_b.Max(b => b.Dish) : 0.0;
            double bonus_a    = 0.0;
            double bonus_b    = 0.0;

            if (RTSettings.Instance.MultipleAntennaMultiplier > 0.0)
            {
                double sum_omni_a = omni_a.Sum(a => a.Omni);
                double sum_omni_b = omni_b.Sum(b => b.Omni);

                bonus_a = (sum_omni_a - max_omni_a) * RTSettings.Instance.MultipleAntennaMultiplier;
                bonus_b = (sum_omni_b - max_omni_b) * RTSettings.Instance.MultipleAntennaMultiplier;
            }

            double max_a    = Math.Max(max_omni_a + bonus_a, max_dish_a);
            double max_b    = Math.Max(max_omni_b + bonus_b, max_dish_b);
            double distance = sat_a.DistanceTo(sat_b);

            omni_a = omni_a.Where(a => MaxDistance(a.Omni + bonus_a, max_b, OmniRangeClamp) >= distance);
            dish_a = dish_a.Where(a => MaxDistance(a.Dish, max_omni_b + bonus_b, OmniRangeClamp) >= distance || MaxDistance(a.Dish, max_dish_b, DishRangeClamp) >= distance);
            omni_b = omni_b.Where(b => MaxDistance(b.Omni + bonus_b, max_a, OmniRangeClamp) >= distance);
            dish_b = dish_b.Where(b => MaxDistance(b.Dish, max_omni_a + bonus_a, OmniRangeClamp) >= distance || MaxDistance(b.Dish, max_dish_a, DishRangeClamp) >= distance);

            var conn_a = omni_a.Concat(dish_a).FirstOrDefault();
            var conn_b = omni_b.Concat(dish_b).FirstOrDefault();

            if (conn_a != null && conn_b != null)
            {
                var interfaces = omni_a.Concat(dish_a).ToList();
                var type       = LinkType.Omni;
                if (dish_a.Contains(conn_a) || dish_b.Contains(conn_b))
                {
                    type = LinkType.Dish;
                }
                return(new NetworkLink <ISatellite>(sat_b, interfaces, type));
            }

            return(null);
        }
Esempio n. 4
0
        public static NetworkLink<ISatellite> GetLink(ISatellite sat_a, ISatellite sat_b)
        {
            var omni_a = sat_a.Antennas.Where(a => a.Omni > 0);
            var omni_b = sat_b.Antennas.Where(b => b.Omni > 0);
            var dish_a = sat_a.Antennas.Where(a => a.Dish > 0 && (a.IsTargetingDirectly(sat_b) || a.IsTargetingActiveVessel(sat_b) || a.IsTargetingPlanet(sat_b, sat_a)));
            var dish_b = sat_b.Antennas.Where(b => b.Dish > 0 && (b.IsTargetingDirectly(sat_a) || b.IsTargetingActiveVessel(sat_a) || b.IsTargetingPlanet(sat_a, sat_b)));

            double max_omni_a = omni_a.Any() ? omni_a.Max(a => a.Omni) : 0.0;
            double max_omni_b = omni_b.Any() ? omni_b.Max(b => b.Omni) : 0.0;
            double max_dish_a = dish_a.Any() ? dish_a.Max(a => a.Dish) : 0.0;
            double max_dish_b = dish_b.Any() ? dish_b.Max(b => b.Dish) : 0.0;
            double bonus_a = 0.0;
            double bonus_b = 0.0;

            if (RTSettings.Instance.MultipleAntennaMultiplier > 0.0)
            {
                double sum_omni_a = omni_a.Sum(a => a.Omni);
                double sum_omni_b = omni_b.Sum(b => b.Omni);

                bonus_a = (sum_omni_a - max_omni_a) * RTSettings.Instance.MultipleAntennaMultiplier;
                bonus_b = (sum_omni_b - max_omni_b) * RTSettings.Instance.MultipleAntennaMultiplier;
            }

            double max_a = Math.Max(max_omni_a + bonus_a, max_dish_a);
            double max_b = Math.Max(max_omni_b + bonus_b, max_dish_b);
            double distance = sat_a.DistanceTo(sat_b);

            omni_a = omni_a.Where(a => MaxDistance(a.Omni + bonus_a, max_b, OmniRangeClamp) >= distance);
            dish_a = dish_a.Where(a => MaxDistance(a.Dish, max_omni_b + bonus_b, OmniRangeClamp) >= distance || MaxDistance(a.Dish, max_dish_b, DishRangeClamp) >= distance);
            omni_b = omni_b.Where(b => MaxDistance(b.Omni + bonus_b, max_a, OmniRangeClamp) >= distance);
            dish_b = dish_b.Where(b => MaxDistance(b.Dish, max_omni_a + bonus_a, OmniRangeClamp) >= distance || MaxDistance(b.Dish, max_dish_a, DishRangeClamp) >= distance);

            var conn_a = omni_a.Concat(dish_a).FirstOrDefault();
            var conn_b = omni_b.Concat(dish_b).FirstOrDefault();

            if (conn_a != null && conn_b != null)
            {
                var interfaces = omni_a.Concat(dish_a).ToList();
                var type = LinkType.Omni;
                if (dish_a.Contains(conn_a) || dish_b.Contains(conn_b)) type = LinkType.Dish;
                return new NetworkLink<ISatellite>(sat_b, interfaces, type);
            }

            return null;
        }
Esempio n. 5
0
        public static Point2D Triangulation(ISatellite s1, double r1, ISatellite s2, double r2, ISatellite s3, double r3)
        {
            if (r1 == 0 || r2 == 0 || r3 == 0)
            {
                Console.WriteLine("*** Error: Las distancias son incorrectas");
                return(null);
            }

            double x1, x2 = 0, y1 = 0, y2;

            try
            {
                //                (X)
                //                /b\
                //           r1  / | \  r2
                //              /  h  \
                //           a /_ r12 _\ g
                //          (s1)       (s2)
                double  r12          = s1.DistanceTo(s2);
                double  h            = 2 * Heron(r1, r12, r2) / r12;
                double  alphaRadians = Math.Sin(h / r1);
                double  ah           = (r1 * Math.Cos(alphaRadians));
                Point2D p1           = (Point2D)s1.GetCoords();
                Point2D p2           = (Point2D)s2.GetCoords();
                Point2D p3           = p1 + ((ah / r12) * (p2 - p1));

                x1 = p3.X + (h * (p2.Y - p1.Y) / r12);
                x2 = p3.X - (h * (p2.Y - p1.Y) / r12);
                y1 = p3.Y + (h * (p2.X - p1.X) / r12);
                y2 = p3.Y + (h * (p2.X - p1.X) / r12);

                // TODO: Select combination with minimun error automatically
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.BackgroundColor = ConsoleColor.DarkGray;
                Console.WriteLine("\tShowing the error in the different solutions of:");
                Console.WriteLine($"\tX={p1} ± ({ah:0.###}/{r12:0.###})({p2}-{p1})");
                Console.WriteLine($"\ts1. Difference distance informed to kenobi vs distance approximated (x1,y1): {Math.Abs(DistanceFromTo(p1, new Point2D(x1, y1)) - r1)}");
                Console.WriteLine($"\ts1. Difference distance informed to kenobi vs distance approximated (x1,y2): {Math.Abs(DistanceFromTo(p1, new Point2D(x1, y2)) - r1)}");
                Console.WriteLine($"\ts1. Difference distance informed to kenobi vs distance approximated (x2,y1): {Math.Abs(DistanceFromTo(p1, new Point2D(x2, y1)) - r1)}");
                Console.WriteLine($"\ts1. Difference distance informed to kenobi vs distance approximated (x2,y2): {Math.Abs(DistanceFromTo(p1, new Point2D(x2, y2)) - r1)}");
                Console.WriteLine($"\ts2. Difference distance informed to skywalker vs distance approximated (x1,y1): {Math.Abs(DistanceFromTo(p2, new Point2D(x1, y1)) - r2)}");
                Console.WriteLine($"\ts2. Difference distance informed to skywalker vs distance approximated (x1,y2): {Math.Abs(DistanceFromTo(p2, new Point2D(x1, y2)) - r2)}");
                Console.WriteLine($"\ts2. Difference distance informed to skywalker vs distance approximated (x2,y1): {Math.Abs(DistanceFromTo(p2, new Point2D(x2, y1)) - r2)}");
                Console.WriteLine($"\ts2. Difference distance informed to skywalker vs distance approximated (x2,y2): {Math.Abs(DistanceFromTo(p2, new Point2D(x2, y2)) - r2)}");
                Console.WriteLine($"\ts3. Difference distance informed to sato vs distance approximated (x1,y1): {Math.Abs(DistanceFromTo((Point2D)s3.GetCoords(), new Point2D(x1, y1)) - r3)}");
                Console.WriteLine($"\ts3. Difference distance informed to sato vs distance approximated (x1,y2): {Math.Abs(DistanceFromTo((Point2D)s3.GetCoords(), new Point2D(x1, y2)) - r3)}");
                Console.WriteLine($"\ts3. Difference distance informed to sato vs distance approximated (x2,y1): {Math.Abs(DistanceFromTo((Point2D)s3.GetCoords(), new Point2D(x2, y1)) - r3)}");
                Console.WriteLine($"\ts3. Difference distance informed to sato vs distance approximated (x2,y2): {Math.Abs(DistanceFromTo((Point2D)s3.GetCoords(), new Point2D(x2, y2)) - r3)}");
                Console.WriteLine("\tThe minimum error is in the 3th and 4th combination, and the right combination is the 3th.");
                Console.ResetColor();
            }
            catch (ArithmeticException e)
            {
                Console.WriteLine(e.Message);
            }

            return(new Point2D()
            {
                X = x2,
                Y = y1
            });
        }