using System; using System.Linq; using System.Text; using System.Drawing; using System.Threading.Tasks; using System.Collections.Generic; using static System.Math; using System.Numerics; /* Función que permite obtener las posiciones de las posibles intersecciones entre dos circulos. PD: le debeo un café a alguien random de internet */ namespace JansenLegSimulator { public class CosasQueNoSeExplicanEnMatesDePrimero { /// /// Gets the intersections of two circles /// /// The first circle's center /// The second circle's center /// The first circle's radius /// The second circle's radius. If omitted, assumed to equal the first circle's radius /// An array of intersection points. May have zero, one, or two values /// Adapted from http://csharphelper.com/blog/2014/09/determine-where-two-circles-intersect-in-c/ public static Vector2[] CalculateCircleIntersections(Vector2 center1, Vector2 center2, double radius1, double? radius2 = null) { // Definir radios. Si sólo se ha dado R1, // asignar valor de R1 a los dos radios var (r1, r2) = (radius1, radius2 ?? radius1); // Definir centros de los circulos. (double x1, double y1, double x2, double y2) = (center1.X, center1.Y, center2.X, center2.Y); // Determinar la distancia entre los dos centros. // Es el módulo del vector que une los dos centros. double d = Sqrt(Pow(x1 - x2, 2) + Pow(y1 - y2, 2)); // Si la suma de radios es menor a la distancia que // une los centros, devolver un array vacío. // No existe intersección. if (!(Abs(r1 - r2) <= d && d <= r1 + r2)) { return new Vector2[0]; } // En este momento, se dan las condiciones para que // por lo menos exista una intersección var dsq = d * d; // Caucular el cuadrado de la distancia (d^2) var (r1sq, r2sq) = (r1 * r1, r2 * r2); // Calcular los cuadrados de los radios (r^2) var r1sq_r2sq = r1sq - r2sq; // Calcular la diferencia de los r^2 (incR^2) var a = r1sq_r2sq / (2 * dsq); // Calcular la división (incR^2)/(2*d^2) var c = Sqrt(2 * (r1sq + r2sq) / dsq - (r1sq_r2sq * r1sq_r2sq) / (dsq * dsq) - 1); // Calcular las componentes de los resultados var fx = (x1 + x2) / 2 + a * (x2 - x1); var gx = c * (y2 - y1) / 2; var fy = (y1 + y2) / 2 + a * (y2 - y1); var gy = c * (x1 - x2) / 2; // Generar los vectores de las intersecciones resultado var i1 = new Vector2((float)(fx + gx), (float)(fy + gy)); var i2 = new Vector2((float)(fx - gx), (float)(fy - gy)); // Si son la misma solucción deveolver sólo i1. // Si son ditintas, devolver ambas soluciones. return i1 == i2 ? new Vector2[] { i1 } : new Vector2[] { i1, i2 }; } } }