Con el agregado de Overlap a los circulos

This commit is contained in:
Miguel 2024-05-08 09:15:28 +02:00
parent ef7d3e2618
commit 294be7788f
2 changed files with 39 additions and 11 deletions

View File

@ -58,6 +58,17 @@ namespace CtrEditor.ObjetosSim
} }
} }
public float Overlap
{
get => Data.Overlap;
set
{
Data.Overlap = value;
OnPropertyChanged(nameof(Overlap));
}
}
public override float LeftPixels public override float LeftPixels
{ {
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Left); get => PixelToMeter.Instance.calc.MetersToPixels(Data.Left);
@ -134,6 +145,7 @@ namespace CtrEditor.ObjetosSim
{ {
Top = Data.Top; Top = Data.Top;
Left = Data.Left; Left = Data.Left;
Overlap = Data.Overlap;
} }
} }

View File

@ -20,15 +20,16 @@ public class Circle
} }
public float Diameter { get; set; } public float Diameter { get; set; }
public float Mass { get; set; } public float Mass { get; set; }
public float Angle { get; set; } // En grados public float AngleofMovement { get; set; } // En grados
public float Speed { get; set; } public float Speed { get; set; }
public float Overlap { get; set; }
public Circle(float left = 0, float top = 0, float diameter = 10, float mass = 1, float angle = 0, float speed = 0) public Circle(float left = 0, float top = 0, float diameter = 10, float mass = 1, float angle = 0, float speed = 0)
{ {
position = new Vector2(left, top); position = new Vector2(left, top);
Diameter = diameter; Diameter = diameter;
Mass = mass; Mass = mass;
Angle = angle; AngleofMovement = angle;
Speed = speed; Speed = speed;
} }
@ -37,6 +38,7 @@ public class Circle
// Convertir timeStep de milisegundos a segundos para la simulación // Convertir timeStep de milisegundos a segundos para la simulación
float timeStepInSeconds = timeStep_ms / 1000.0f; float timeStepInSeconds = timeStep_ms / 1000.0f;
bool isTracted = false; // Indicador para verificar si el círculo está siendo traccionado bool isTracted = false; // Indicador para verificar si el círculo está siendo traccionado
Overlap = 0;
// Aplicar fuerza desde el rectángulo si está sobre uno // Aplicar fuerza desde el rectángulo si está sobre uno
foreach (var rectangle in rectangles) foreach (var rectangle in rectangles)
@ -44,6 +46,7 @@ public class Circle
float overlap = CalculateOverlapPercentage(this, rectangle); float overlap = CalculateOverlapPercentage(this, rectangle);
if (overlap > 0) if (overlap > 0)
{ {
Overlap += overlap;
isTracted = true; // El círculo está siendo traccionado por un rectángulo isTracted = true; // El círculo está siendo traccionado por un rectángulo
// Convertir la velocidad del rectángulo de metros por minuto a metros por segundo // Convertir la velocidad del rectángulo de metros por minuto a metros por segundo
float rectangleSpeedInMetersPerSecond = rectangle.Speed / 60.0f; float rectangleSpeedInMetersPerSecond = rectangle.Speed / 60.0f;
@ -60,7 +63,7 @@ public class Circle
Speed += (rectangleSpeedInMetersPerSecond - Speed) * (overlap / 100.0f) * timeStepInSeconds; Speed += (rectangleSpeedInMetersPerSecond - Speed) * (overlap / 100.0f) * timeStepInSeconds;
} }
Angle = rectangle.Angle; AngleofMovement = rectangle.Angle;
} }
} }
@ -100,11 +103,11 @@ public class Circle
float impactAngle = CalculateImpactAngle(this, line); float impactAngle = CalculateImpactAngle(this, line);
if (impactAngle < 85) if (impactAngle < 85)
{ {
Angle = line.Angle; AngleofMovement = line.Angle;
} }
else if (impactAngle > 95) else if (impactAngle > 95)
{ {
Angle = line.Angle + 180; // Movimiento contrario AngleofMovement = line.Angle + 180; // Movimiento contrario
} }
else else
{ {
@ -114,7 +117,7 @@ public class Circle
} }
// Calcular nueva posición // Calcular nueva posición
Vector2 direction = new Vector2((float)Math.Cos(Angle * Math.PI / 180), (float)Math.Sin(Angle * Math.PI / 180)); Vector2 direction = new Vector2((float)Math.Cos(AngleofMovement * Math.PI / 180), (float)Math.Sin(AngleofMovement * Math.PI / 180));
Vector2 velocity = direction * Speed * timeStepInSeconds; Vector2 velocity = direction * Speed * timeStepInSeconds;
position += velocity; position += velocity;
} }
@ -180,7 +183,7 @@ public class Circle
private float CalculateImpactAngle(Circle circle, Line line) private float CalculateImpactAngle(Circle circle, Line line)
{ {
Vector2 movementDirection = new Vector2((float)Math.Cos(circle.Angle * Math.PI / 180), (float)Math.Sin(circle.Angle * Math.PI / 180)); Vector2 movementDirection = new Vector2((float)Math.Cos(circle.AngleofMovement * Math.PI / 180), (float)Math.Sin(circle.AngleofMovement * Math.PI / 180));
Vector2 lineDirection = line.end - line.start; Vector2 lineDirection = line.end - line.start;
Vector2 lineNormal = new Vector2(-lineDirection.Y, lineDirection.X); // Rotar 90 grados para obtener normal Vector2 lineNormal = new Vector2(-lineDirection.Y, lineDirection.X); // Rotar 90 grados para obtener normal
lineNormal = Vector2.Normalize(lineNormal); lineNormal = Vector2.Normalize(lineNormal);
@ -233,14 +236,27 @@ public class Circle
private float EstimateOverlapArea(Vector2 circleCenter, float radius, Vector2 rectCenter, float length, float width) private float EstimateOverlapArea(Vector2 circleCenter, float radius, Vector2 rectTopLeft, float length, float width)
{ {
// Esto es un placeholder: el cálculo real requiere un algoritmo geométrico complejo float rectRight = rectTopLeft.X + length;
// Puedes retornar una estimación basada en proporciones o usar una librería geométrica float rectBottom = rectTopLeft.Y + width;
return (float) (radius * radius * Math.PI * 0.25f); // Asumiendo un solapamiento del 25% como placeholder float distToLeft = Math.Max(0, rectTopLeft.X - circleCenter.X);
float distToRight = Math.Max(0, circleCenter.X - rectRight);
float distToTop = Math.Max(0, rectTopLeft.Y - circleCenter.Y);
float distToBottom = Math.Max(0, circleCenter.Y - rectBottom);
float distToNearestEdge = Math.Min(Math.Min(distToLeft, distToRight), Math.Min(distToTop, distToBottom));
if (distToNearestEdge >= radius)
return 0; // No overlap
float overlapRadius = radius - distToNearestEdge;
float overlapArea = (float)(Math.PI * overlapRadius * overlapRadius);
return Math.Min(overlapArea, (float)(Math.PI * radius * radius)); // Cap at circle area
} }
private Vector2 RotatePoint(Vector2 point, Vector2 pivot, float angle) private Vector2 RotatePoint(Vector2 point, Vector2 pivot, float angle)
{ {
float cosTheta = (float)Math.Cos(angle); float cosTheta = (float)Math.Cos(angle);