CtrEditor/Simulacion/InterseccionCirculoRectangu...

74 lines
2.4 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic.Devices;
2024-05-25 09:38:36 -03:00
using nkast.Aether.Physics2D.Common;
namespace CtrEditor.Simulacion
{
internal class InterseccionCirculoRectangulo
{
// Definición de la función CalcularSuperficieCompartida
2024-05-30 13:48:37 -03:00
public static float CalcularSuperficieCompartida(Vector2[] vertices, Vector2 center, float radio)
{
2024-05-30 13:48:37 -03:00
float totalCircleArea = (float) (Math.PI * radio * radio);
// Distancia a líneas ajustado
float[] distances = new float[4];
for (int i = 0; i < 4; i++)
{
distances[i] = DistanceFromLine(center, vertices[i], vertices[(i + 1) % 4]);
}
float minDistance = float.MaxValue;
foreach (var dist in distances)
{
if (Math.Abs(dist) < Math.Abs(minDistance))
minDistance = dist;
}
float d = Math.Abs(minDistance);
float sharedArea = 0;
2024-05-30 13:48:37 -03:00
if (Array.TrueForAll(distances, dist => Math.Abs(dist) > radio))
{
sharedArea = totalCircleArea;
}
2024-05-30 13:48:37 -03:00
else if (d < radio)
{
2024-05-30 13:48:37 -03:00
float cosTheta = Math.Min(1, d / radio);
float sinTheta = (float)Math.Sqrt(Math.Max(0, radio * radio - d * d));
if (minDistance < 0) // El centro está dentro del rectángulo
{
2024-05-30 13:48:37 -03:00
float areaOutside = radio * radio * (float)Math.Acos(cosTheta) - d * sinTheta;
sharedArea = totalCircleArea - areaOutside;
}
else // El centro está fuera del rectángulo
{
2024-05-30 13:48:37 -03:00
sharedArea = radio * radio * (float)Math.Acos(cosTheta) - d * sinTheta;
}
}
else
{
sharedArea = 0;
}
2024-05-30 13:48:37 -03:00
var area = (sharedArea / totalCircleArea) * 1.1f;
return area > 1 ? 1 : area;
}
public static float DistanceFromLine(Vector2 point, Vector2 start, Vector2 end)
{
float A = end.Y - start.Y;
float B = start.X - end.X;
float C = end.X * start.Y - start.X * end.Y;
float distance = (A * point.X + B * point.Y + C) / (float)Math.Sqrt(A * A + B * B);
return distance;
}
}
2024-05-30 13:48:37 -03:00
}