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 }); }