diff --git a/CtrEditor.csproj b/CtrEditor.csproj
index c85b1c1..98043c8 100644
--- a/CtrEditor.csproj
+++ b/CtrEditor.csproj
@@ -10,6 +10,7 @@
+
@@ -44,10 +45,12 @@
+
+
diff --git a/ObjetosSim/Dinamicos/ucBotella.xaml.cs b/ObjetosSim/Dinamicos/ucBotella.xaml.cs
index b42291f..abd3182 100644
--- a/ObjetosSim/Dinamicos/ucBotella.xaml.cs
+++ b/ObjetosSim/Dinamicos/ucBotella.xaml.cs
@@ -1,10 +1,11 @@
using System.Windows;
using System.Windows.Controls;
-using Microsoft.Xna.Framework;
+//using using Microsoft.Xna.Framework;
using CtrEditor.Convertidores;
using CtrEditor.Siemens;
using CtrEditor.Simulacion;
using CommunityToolkit.Mvvm.ComponentModel;
+using nkast.Aether.Physics2D.Common;
namespace CtrEditor.ObjetosSim
{
diff --git a/ObjetosSim/Estaticos/ucDescarte.xaml.cs b/ObjetosSim/Estaticos/ucDescarte.xaml.cs
index d833e97..8052d58 100644
--- a/ObjetosSim/Estaticos/ucDescarte.xaml.cs
+++ b/ObjetosSim/Estaticos/ucDescarte.xaml.cs
@@ -3,7 +3,7 @@ using CtrEditor.Siemens;
using CtrEditor.Simulacion;
using System.Windows;
using System.Windows.Controls;
-using Microsoft.Xna.Framework;
+using nkast.Aether.Physics2D.Common;
using System.Windows.Media.Animation;
using CommunityToolkit.Mvvm.ComponentModel;
namespace CtrEditor.ObjetosSim
diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs
index da41636..7a20424 100644
--- a/ObjetosSim/osBase.cs
+++ b/ObjetosSim/osBase.cs
@@ -15,7 +15,7 @@ using CtrEditor.Convertidores;
using CtrEditor.Siemens;
using CtrEditor.Simulacion;
using System.Windows.Media;
-using Microsoft.Xna.Framework;
+using nkast.Aether.Physics2D.Common;
using FarseerPhysics.Dynamics;
using Siemens.Simatic.Simulation.Runtime;
using System.Windows.Media.Imaging;
diff --git a/Simulacion/Aether.cs b/Simulacion/Aether.cs
new file mode 100644
index 0000000..f90b8d7
--- /dev/null
+++ b/Simulacion/Aether.cs
@@ -0,0 +1,641 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Shapes;
+using CtrEditor.Convertidores;
+using System.Windows;
+using System.Diagnostics;
+using CtrEditor.ObjetosSim;
+using System.Windows.Documents;
+using nkast.Aether.Physics2D;
+using nkast.Aether.Physics2D.Dynamics;
+using nkast.Aether.Physics2D.Common;
+using nkast.Aether.Physics2D.Collision.Shapes;
+
+namespace CtrEditor.Simulacion
+{
+ public class simBase
+ {
+ public Body Body { get; protected set; }
+ public World _world;
+
+ public void RemoverBody()
+ {
+ if (Body != null)
+ {
+ _world.Remove(Body);
+ }
+ }
+ public void SetPosition(float x, float y)
+ {
+ Body.SetTransform(new Vector2(x, y), Body.Rotation);
+ }
+ public void SetPosition(Vector2 centro)
+ {
+ Body.SetTransform(centro, Body.Rotation);
+ }
+ }
+
+ public class simCurve : simBase
+ {
+ private float _innerRadius;
+ private float _outerRadius;
+ private float _startAngle;
+ private float _endAngle;
+ public float Speed { get; set; } // Velocidad para efectos de cinta transportadora
+
+ public simCurve(World world, float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
+ {
+ _world = world;
+ _innerRadius = innerRadius;
+ _outerRadius = outerRadius;
+ _startAngle = Microsoft.Xna.Framework.MathHelper.ToRadians(startAngle);
+ _endAngle = Microsoft.Xna.Framework.MathHelper.ToRadians(endAngle);
+ Create(position);
+ }
+
+ public void Create(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
+ {
+ if (_world == null) return;
+ _innerRadius = innerRadius;
+ _outerRadius = outerRadius;
+ _startAngle = Microsoft.Xna.Framework.MathHelper.ToRadians(startAngle);
+ _endAngle = Microsoft.Xna.Framework.MathHelper.ToRadians(endAngle);
+ Create(position);
+ }
+
+ public void Create(Vector2 position)
+ {
+ RemoverBody();
+
+ // Crear la geometría del sensor de curva
+ List segments = CreateCurveVertices(_innerRadius, _outerRadius, _startAngle, _endAngle);
+ Body = new Body();
+ foreach (var segment in segments)
+ {
+ var shape = new PolygonShape(segment, 1f);
+ var fixture = Body.CreateFixture(shape);
+ fixture.IsSensor = true;
+ }
+ Body.Position = position;
+ Body.BodyType = BodyType.Static;
+ Body.Tag = this;
+ }
+
+ public void SetSpeed(float speed)
+ {
+ Speed = speed;
+ }
+
+ private List CreateCurveVertices(float innerRadius, float outerRadius, float startAngle, float endAngle)
+ {
+ List verticesList = new List();
+ int segments = 32;
+ float angleStep = (endAngle - startAngle) / segments;
+
+ Vertices innerVertices = new Vertices();
+ Vertices outerVertices = new Vertices();
+
+ for (int i = 0; i <= segments; i++)
+ {
+ float angle = startAngle + i * angleStep;
+ innerVertices.Add(new Vector2(innerRadius * (float)Math.Cos(angle), innerRadius * (float)Math.Sin(angle)));
+ outerVertices.Add(new Vector2(outerRadius * (float)Math.Cos(angle), outerRadius * (float)Math.Sin(angle)));
+ }
+
+ outerVertices.Reverse();
+ innerVertices.AddRange(outerVertices);
+ verticesList.Add(innerVertices);
+
+ return verticesList;
+ }
+
+ public void ApplyCurveEffect(Fixture bottle)
+ {
+ Vector2 centerToBottle = bottle.Body.Position - Body.Position;
+ float distanceToCenter = centerToBottle.Length();
+
+ if (distanceToCenter >= _innerRadius && distanceToCenter <= _outerRadius)
+ {
+ // Calcular la velocidad tangencial
+ float speedMetersPerSecond = Speed / 60.0f;
+ float angularVelocity = speedMetersPerSecond / distanceToCenter;
+
+ // Vector tangente (perpendicular al radio)
+ Vector2 tangent = new Vector2(-centerToBottle.Y, centerToBottle.X);
+ tangent.Normalize();
+
+ // Velocidad deseada
+ Vector2 desiredVelocity = tangent * angularVelocity * distanceToCenter;
+ bottle.Body.LinearVelocity = desiredVelocity;
+ }
+ }
+ }
+
+
+ public class simDescarte : simBase
+ {
+ private float _radius;
+
+ public simDescarte(World world, float diameter, Vector2 position)
+ {
+ _world = world;
+ _radius = diameter / 2;
+ Create(position);
+ }
+
+ public void SetDiameter(float diameter)
+ {
+ _radius = diameter / 2;
+ Create(Body.Position); // Recrear el círculo con el nuevo tamaño
+ }
+
+ public void Create(Vector2 position)
+ {
+ RemoverBody();
+ Body = _world.CreateCircle(_radius, 1f, position);
+
+ Body.FixtureList[0].IsSensor = true;
+ Body.BodyType = BodyType.Static;
+ Body.Tag = this; // Importante para la identificación durante la colisión
+ }
+ }
+
+
+ public class simTransporte : simBase
+ {
+ public float Speed { get; set; } // Velocidad para efectos de cinta transportadora
+ public float DistanceGuide2Guide { get; set; }
+ public bool TransportWithGuides = false;
+
+ public simTransporte(World world, float width, float height, Vector2 position, float angle = 0)
+ {
+ _world = world;
+ Create(width, height, position, angle);
+ }
+
+ public float Angle
+ {
+ get { return Microsoft.Xna.Framework.MathHelper.ToDegrees(Body.Rotation); }
+ set { Body.Rotation = Microsoft.Xna.Framework.MathHelper.ToRadians(value); }
+ }
+
+ public new void SetPosition(float x, float y)
+ {
+ Body.Position = new Vector2(x, y);
+ }
+
+ public void SetSpeed(float speed)
+ {
+ Speed = speed;
+ }
+
+ public void SetDimensions(float width, float height)
+ {
+ Body.Remove(Body.FixtureList[0]);
+
+ var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f);
+ Body.CreateFixture(newShape);
+ }
+ public void Create(float width, float height, Vector2 position, float angle = 0)
+ {
+ RemoverBody();
+ Body = _world.CreateRectangle( width, height, 1f, position);
+ Body.FixtureList[0].IsSensor = true;
+ Body.BodyType = BodyType.Static;
+ Body.Rotation = Microsoft.Xna.Framework.MathHelper.ToRadians(angle);
+ Body.Tag = this; // Importante para la identificación durante la colisión
+ }
+ }
+
+ public class simBarrera : simBase
+ {
+ public bool LuzCortada = false;
+
+ public simBarrera(World world, float width, float height, Vector2 position, float angle = 0)
+ {
+ _world = world;
+ Create(width, height, position, angle);
+ }
+
+ public float Angle
+ {
+ get { return Microsoft.Xna.Framework.MathHelper.ToDegrees(Body.Rotation); }
+ set { Body.Rotation = Microsoft.Xna.Framework.MathHelper.ToRadians(value); }
+ }
+
+ public new void SetPosition(float x, float y)
+ {
+ Body.Position = new Vector2(x, y);
+ }
+
+ public void SetDimensions(float width, float height)
+ {
+ Body.Remove(Body.FixtureList[0]);
+
+ var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f);
+ Body.CreateFixture(newShape);
+ }
+
+ public void Create(float width, float height, Vector2 position, float angle = 0)
+ {
+ RemoverBody();
+ Body = _world.CreateRectangle( width, height, 1f, position);
+ Body.FixtureList[0].IsSensor = true;
+ Body.BodyType = BodyType.Static;
+ Body.Rotation = Microsoft.Xna.Framework.MathHelper.ToRadians(angle);
+ Body.Tag = this; // Importante para la identificación durante la colisión
+ LuzCortada = false;
+ }
+ }
+
+ public class simGuia : simBase
+ {
+ public simGuia(World world, Vector2 start, Vector2 end)
+ {
+ _world = world;
+ Create(start, end);
+ }
+
+ public void Create(Vector2 start, Vector2 end)
+ {
+ RemoverBody();
+ Body = _world.CreateEdge( start, end);
+ Body.BodyType = BodyType.Static;
+ Body.Tag = this; // Importante para la identificación durante la colisión
+ }
+
+ public void UpdateVertices(Vector2 newStart, Vector2 newEnd)
+ {
+ Create(newStart, newEnd); // Recrear la línea con nuevos vértices
+ }
+ }
+
+ public class simBotella : simBase
+ {
+ private float _radius;
+ private float _mass;
+ public bool Descartar = false;
+
+ public simBotella(World world, float diameter, Vector2 position, float mass)
+ {
+ _world = world;
+ _radius = diameter / 2;
+ _mass = mass;
+ Create(position);
+ }
+
+ public float CenterX
+ {
+ get { return Body.Position.X; }
+ set { }
+ }
+
+ public float CenterY
+ {
+ get { return Body.Position.Y; }
+ set { }
+ }
+
+ public Vector2 Center
+ {
+ get { return Body.Position; }
+ }
+
+ public float Mass
+ {
+ get
+ {
+ if (_mass <= 0)
+ _mass = 1;
+ return _mass;
+ }
+ set { _mass = value; }
+ }
+
+ private void Create(Vector2 position)
+ {
+ RemoverBody();
+ Body = _world.CreateCircle( _radius, 0.2f, position);
+ Body.BodyType = BodyType.Dynamic;
+
+ // Restablecer manejador de eventos de colisión
+ Body.OnCollision += HandleCollision;
+ //Body.OnSeparation += HandleOnSeparation;
+
+ Body.Tag = this; // Importante para la identificación durante la colisión
+
+ // Configurar la fricción
+ Body.SetFriction(0.3f);
+
+ // Configurar amortiguamiento
+ Body.LinearDamping = 0.4f; // Ajustar para controlar la reducción de la velocidad lineal
+ Body.AngularDamping = 0.4f; // Ajustar para controlar la reducción de la velocidad angular
+ Body.SetRestitution(0.2f); // Baja restitución para menos rebote
+
+ Body.IsBullet = true;
+ }
+
+ public void SetDiameter(float diameter)
+ {
+ _radius = diameter / 2;
+ Create(Body.Position); // Recrear el círculo con el nuevo tamaño
+ }
+
+ public void SetMass(float mass)
+ {
+ Mass = mass;
+ }
+
+ private bool HandleCollision(Fixture fixtureA, Fixture fixtureB, nkast.Aether.Physics2D.Dynamics.Contacts.Contact contact)
+ {
+ if (fixtureB.Body.Tag is simBarrera Sensor)
+ {
+ Sensor.LuzCortada = true;
+ return true;
+ }
+ else if (fixtureB.Body.Tag is simCurve curve)
+ {
+ curve.ApplyCurveEffect(fixtureA);
+ return true; // No aplicar respuestas físicas
+ }
+ else if (fixtureB.Body.Tag is simDescarte)
+ {
+ Descartar = true;
+ return true;
+ }
+ else if (fixtureB.Body.Tag is simTransporte)
+ {
+ simTransporte conveyor = fixtureB.Body.Tag as simTransporte;
+
+ if (conveyor.Speed != 0)
+ {
+
+ CircleShape circleShape = fixtureA.Shape as CircleShape;
+ PolygonShape polygonShape = fixtureB.Shape as PolygonShape;
+
+ // Obtener centro y radio del círculo
+ Vector2 centroCirculo = fixtureA.Body.Position;
+ float radio = circleShape.Radius;
+
+ // Obtener los vértices del polígono (rectángulo)
+ Vector2[] vertices = new Vector2[polygonShape.Vertices.Count];
+ float cos = (float)Math.Cos(fixtureB.Body.Rotation);
+ float sin = (float)Math.Sin(fixtureB.Body.Rotation);
+
+ for (int i = 0; i < polygonShape.Vertices.Count; i++)
+ {
+ Vector2 vertex = polygonShape.Vertices[i];
+ float rotatedX = vertex.X * cos - vertex.Y * sin + fixtureB.Body.Position.X;
+ float rotatedY = vertex.X * sin + vertex.Y * cos + fixtureB.Body.Position.Y;
+ vertices[i] = new Vector2(rotatedX, rotatedY);
+ }
+
+ // Calcular el porcentaje de la superficie compartida
+ float porcentajeCompartido = InterseccionCirculoRectanguloAether.CalcularSuperficieCompartida(vertices, centroCirculo, radio);
+
+ // Aplicar el efecto del transportador usando el porcentaje calculado
+ //if (conveyor.TransportWithGuides)
+ // if (conveyor.DistanceGuide2Guide <= radio * 2)
+ // CenterFixtureOnConveyor(fixtureA, conveyor);
+ ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido);
+
+ }
+ return true; // No aplicar respuestas físicas
+ }
+ return true; // No aplicar respuestas físicas
+ }
+
+ private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido)
+ {
+ float speedMetersPerSecond = conveyor.Speed / 60.0f;
+ Vector2 desiredVelocity = new Vector2((float)Math.Cos(conveyor.Body.Rotation), (float)Math.Sin(conveyor.Body.Rotation)) * speedMetersPerSecond;
+ circleFixture.Body.LinearVelocity += desiredVelocity * porcentajeCompartido;
+ }
+
+ private void CenterFixtureOnConveyor(Fixture fixtureA, simTransporte conveyor)
+ {
+ // Obtener el centro del conveyor
+ Vector2 conveyorCenter = conveyor.Body.Position;
+
+ // Calcular el vector de la línea horizontal centrada de conveyor
+ float halfDistance = conveyor.DistanceGuide2Guide / 2;
+ float cos = (float)Math.Cos(conveyor.Body.Rotation);
+ float sin = (float)Math.Sin(conveyor.Body.Rotation);
+
+ Vector2 offset = new Vector2(halfDistance * cos, halfDistance * sin);
+
+ // Línea horizontal centrada de conveyor en el espacio del mundo
+ Vector2 lineStart = conveyorCenter - offset;
+ Vector2 lineEnd = conveyorCenter + offset;
+
+ // Proyectar el centro de fixtureA sobre la línea horizontal
+ Vector2 fixtureCenter = fixtureA.Body.Position;
+ Vector2 closestPoint = ProjectPointOntoLine(fixtureCenter, lineStart, lineEnd);
+
+ // Mover fixtureA al punto más cercano en la línea horizontal
+ fixtureA.Body.Position = closestPoint;
+ }
+
+ private Vector2 ProjectPointOntoLine(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
+ {
+ Vector2 lineDirection = lineEnd - lineStart;
+ lineDirection.Normalize();
+
+ Vector2 pointToLineStart = point - lineStart;
+ Vector2.Dot(ref pointToLineStart,ref lineDirection, out float projectionLength);
+
+ return lineStart + projectionLength * lineDirection;
+ }
+ }
+
+ public class SimulationManagerFP
+ {
+ private World world;
+ private Canvas simulationCanvas;
+ public List Cuerpos;
+
+ private Stopwatch stopwatch;
+ private double stopwatch_last;
+
+ public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; }
+
+ public SimulationManagerFP()
+ {
+ world = new World(new Vector2(0, 0)); // Vector2.Zero
+ Cuerpos = new List();
+ stopwatch = new Stopwatch();
+ stopwatch.Start();
+ }
+
+ public void Clear()
+ {
+ if (world.BodyList.Count > 0)
+ world.Clear();
+ if (Cuerpos.Count > 0)
+ Cuerpos.Clear();
+ }
+
+ public void Step()
+ {
+ // Detener el cronómetro y obtener el tiempo transcurrido en milisegundos
+ float elapsedMilliseconds = (float)(stopwatch.Elapsed.TotalMilliseconds - stopwatch_last);
+ stopwatch_last = stopwatch.Elapsed.TotalMilliseconds;
+
+ // Pasar el tiempo transcurrido al método Step
+ world.Step(elapsedMilliseconds / 1000.0f);
+ }
+
+ public void Remove(simBase Objeto)
+ {
+ if (Objeto != null)
+ {
+ Objeto.RemoverBody();
+ Cuerpos.Remove(Objeto);
+ }
+ }
+
+ public simCurve AddCurve(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
+ {
+ simCurve curva = new simCurve(world, innerRadius, outerRadius, startAngle, endAngle, position);
+ Cuerpos.Add(curva);
+ return curva;
+ }
+
+ public simBotella AddCircle(float diameter, Vector2 position, float mass)
+ {
+ simBotella circle = new simBotella(world, diameter, position, mass);
+ Cuerpos.Add(circle);
+ return circle;
+ }
+
+ public simTransporte AddRectangle(float width, float height, Vector2 position, float angle)
+ {
+ simTransporte rectangle = new simTransporte(world, width, height, position, angle);
+ Cuerpos.Add(rectangle);
+ return rectangle;
+ }
+
+ public simBarrera AddBarrera(float width, float height, Vector2 position, float angle)
+ {
+ simBarrera rectangle = new simBarrera(world, width, height, position, angle);
+ Cuerpos.Add(rectangle);
+ return rectangle;
+ }
+
+ public simGuia AddLine(Vector2 start, Vector2 end)
+ {
+ simGuia line = new simGuia(world, start, end);
+ Cuerpos.Add(line);
+ return line;
+ }
+
+ public simDescarte AddDescarte(float diameter, Vector2 position)
+ {
+ simDescarte descarte = new simDescarte(world, diameter, position);
+ Cuerpos.Add(descarte);
+ return descarte;
+ }
+
+ public void Debug_DrawInitialBodies()
+ {
+ Debug_ClearSimulationShapes();
+ world.Step(0.01f); // Para actualizar la BodyList
+ foreach (Body body in world.BodyList)
+ {
+ foreach (Fixture fixture in body.FixtureList)
+ {
+ DrawShape(fixture);
+ }
+ }
+ }
+
+ public void Debug_ClearSimulationShapes()
+ {
+ var simulationShapes = simulationCanvas.Children.OfType().Where(s => s.Tag as string == "Simulation").ToList();
+ foreach (var shape in simulationShapes)
+ {
+ simulationCanvas.Children.Remove(shape);
+ }
+ }
+
+ private void DrawShape(Fixture fixture)
+ {
+ System.Windows.Shapes.Shape shape;
+ switch (fixture.Shape.ShapeType)
+ {
+ case ShapeType.Circle:
+ shape = DrawCircle(fixture);
+ break;
+ case ShapeType.Polygon:
+ shape = DrawPolygon(fixture);
+ break;
+ case ShapeType.Edge:
+ shape = DrawEdge(fixture);
+ break;
+ default:
+ return;
+ }
+ shape.Tag = "Simulation"; // Marcar para simulación
+ Canvas.SetZIndex(shape, 20);
+ simulationCanvas.Children.Add(shape);
+ }
+
+ private float p(float x)
+ {
+ float c = PixelToMeter.Instance.calc.MetersToPixels(x);
+ return c;
+ }
+
+ private System.Windows.Shapes.Shape DrawEdge(Fixture fixture)
+ {
+ EdgeShape edge = fixture.Shape as EdgeShape;
+ Line line = new Line
+ {
+ X1 = p(edge.Vertex1.X + fixture.Body.Position.X), // Aplicar escala y posición
+ Y1 = p(edge.Vertex1.Y + fixture.Body.Position.Y),
+ X2 = p(edge.Vertex2.X + fixture.Body.Position.X),
+ Y2 = p(edge.Vertex2.Y + fixture.Body.Position.Y),
+ Stroke = Brushes.Black,
+ StrokeThickness = 2
+ };
+ return line;
+ }
+
+ private System.Windows.Shapes.Shape DrawCircle(Fixture fixture)
+ {
+ CircleShape circle = fixture.Shape as CircleShape;
+ Ellipse ellipse = new Ellipse
+ {
+ Width = p(circle.Radius * 2), // Escalado para visualización
+ Height = p(circle.Radius * 2), // Escalado para visualización
+ Stroke = Brushes.Black,
+ StrokeThickness = 2
+ };
+ Canvas.SetLeft(ellipse, p(fixture.Body.Position.X - circle.Radius));
+ Canvas.SetTop(ellipse, p(fixture.Body.Position.Y - circle.Radius));
+ return ellipse;
+ }
+
+ private System.Windows.Shapes.Shape DrawPolygon(Fixture fixture)
+ {
+ Polygon polygon = new Polygon { Stroke = Brushes.Black, StrokeThickness = 2 };
+ PolygonShape polyShape = fixture.Shape as PolygonShape;
+
+ float cos = (float)Math.Cos(fixture.Body.Rotation);
+ float sin = (float)Math.Sin(fixture.Body.Rotation);
+
+ foreach (Vector2 vertex in polyShape.Vertices)
+ {
+ float rotatedX = vertex.X * cos - vertex.Y * sin + fixture.Body.Position.X;
+ float rotatedY = vertex.X * sin + vertex.Y * cos + fixture.Body.Position.Y;
+
+ polygon.Points.Add(new Point(p(rotatedX), p(rotatedY)));
+ }
+
+ return polygon;
+ }
+ }
+}
diff --git a/Simulacion/FPhysics.cs b/Simulacion/FPhysics.cs
index 2a55dae..ef8bf7e 100644
--- a/Simulacion/FPhysics.cs
+++ b/Simulacion/FPhysics.cs
@@ -7,7 +7,7 @@ using System.Windows.Shapes;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;
using FarseerPhysics.Collision.Shapes;
-using Microsoft.Xna.Framework;
+using nkast.Aether.Physics2D.Common;
using CtrEditor.Convertidores;
using FarseerPhysics.Common;
using System.Windows;
diff --git a/Simulacion/InterseccionCirculoRectangulo.cs b/Simulacion/InterseccionCirculoRectangulo.cs
index 046008d..2925ff6 100644
--- a/Simulacion/InterseccionCirculoRectangulo.cs
+++ b/Simulacion/InterseccionCirculoRectangulo.cs
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using FarseerPhysics.Collision;
using Microsoft.VisualBasic.Devices;
-using Microsoft.Xna.Framework;
+using nkast.Aether.Physics2D.Common;
namespace CtrEditor.Simulacion
{
@@ -68,6 +68,67 @@ namespace CtrEditor.Simulacion
}
}
+
+ internal class InterseccionCirculoRectanguloAether
+ {
+ // Definición de la función CalcularSuperficieCompartida
+ public static float CalcularSuperficieCompartida(nkast.Aether.Physics2D.Common.Vector2[] vertices, nkast.Aether.Physics2D.Common.Vector2 center, float r)
+ {
+ float totalCircleArea = (float)Math.PI * r * r;
+
+ // 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;
+ if (Array.TrueForAll(distances, dist => Math.Abs(dist) > r))
+ {
+ sharedArea = totalCircleArea;
+ }
+ else if (d < r)
+ {
+ float cosTheta = Math.Min(1, d / r);
+ float sinTheta = (float)Math.Sqrt(Math.Max(0, r * r - d * d));
+ if (minDistance < 0) // El centro está dentro del rectángulo
+ {
+ float areaOutside = r * r * (float)Math.Acos(cosTheta) - d * sinTheta;
+ sharedArea = totalCircleArea - areaOutside;
+ }
+ else // El centro está fuera del rectángulo
+ {
+ sharedArea = r * r * (float)Math.Acos(cosTheta) - d * sinTheta;
+ }
+ }
+ else
+ {
+ sharedArea = 0;
+ }
+
+ return sharedArea / totalCircleArea;
+ }
+
+ public static float DistanceFromLine(nkast.Aether.Physics2D.Common.Vector2 point, nkast.Aether.Physics2D.Common.Vector2 start, nkast.Aether.Physics2D.Common.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;
+ }
+
+ }
+
}