76 lines
3.3 KiB
C#
76 lines
3.3 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Gets the intersections of two circles
|
|
/// </summary>
|
|
/// <param name="center1">The first circle's center</param>
|
|
/// <param name="center2">The second circle's center</param>
|
|
/// <param name="radius1">The first circle's radius</param>
|
|
/// <param name="radius2">The second circle's radius. If omitted, assumed to equal the first circle's radius</param>
|
|
/// <returns>An array of intersection points. May have zero, one, or two values</returns>
|
|
/// <remarks>Adapted from http://csharphelper.com/blog/2014/09/determine-where-two-circles-intersect-in-c/</remarks>
|
|
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 };
|
|
}
|
|
}
|
|
}
|