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
{
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Left);
@ -134,6 +145,7 @@ namespace CtrEditor.ObjetosSim
{
Top = Data.Top;
Left = Data.Left;
Overlap = Data.Overlap;
}
}

View File

@ -20,15 +20,16 @@ public class Circle
}
public float Diameter { 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 Overlap { get; set; }
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);
Diameter = diameter;
Mass = mass;
Angle = angle;
AngleofMovement = angle;
Speed = speed;
}
@ -37,6 +38,7 @@ public class Circle
// Convertir timeStep de milisegundos a segundos para la simulación
float timeStepInSeconds = timeStep_ms / 1000.0f;
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
foreach (var rectangle in rectangles)
@ -44,6 +46,7 @@ public class Circle
float overlap = CalculateOverlapPercentage(this, rectangle);
if (overlap > 0)
{
Overlap += overlap;
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
float rectangleSpeedInMetersPerSecond = rectangle.Speed / 60.0f;
@ -60,7 +63,7 @@ public class Circle
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);
if (impactAngle < 85)
{
Angle = line.Angle;
AngleofMovement = line.Angle;
}
else if (impactAngle > 95)
{
Angle = line.Angle + 180; // Movimiento contrario
AngleofMovement = line.Angle + 180; // Movimiento contrario
}
else
{
@ -114,7 +117,7 @@ public class Circle
}
// 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;
position += velocity;
}
@ -180,7 +183,7 @@ public class Circle
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 lineNormal = new Vector2(-lineDirection.Y, lineDirection.X); // Rotar 90 grados para obtener normal
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
// Puedes retornar una estimación basada en proporciones o usar una librería geométrica
return (float) (radius * radius * Math.PI * 0.25f); // Asumiendo un solapamiento del 25% como placeholder
float rectRight = rectTopLeft.X + length;
float rectBottom = rectTopLeft.Y + width;
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)
{
float cosTheta = (float)Math.Cos(angle);