diff --git a/CtrEditor.csproj b/CtrEditor.csproj
index 17f0cd1..121c8c3 100644
--- a/CtrEditor.csproj
+++ b/CtrEditor.csproj
@@ -8,11 +8,27 @@
true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MainViewModel.cs b/MainViewModel.cs
index edd1f03..b09dfca 100644
--- a/MainViewModel.cs
+++ b/MainViewModel.cs
@@ -24,6 +24,7 @@ using System.Windows.Data;
using System.Windows;
using static System.Resources.ResXFileRef;
using CtrEditor.Convertidores;
+using CtrEditor.Simulacion;
namespace CtrEditor
{
@@ -36,7 +37,7 @@ namespace CtrEditor
private ObservableCollection _objetosSimulables = new ObservableCollection();
public PLCViewModel _plcViewModelData;
- private SimulationManager simulationManager = new SimulationManager();
+ public SimulationManagerFP simulationManager = new SimulationManagerFP();
private readonly DispatcherTimer _timerSimulacion;
@@ -63,7 +64,7 @@ namespace CtrEditor
ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick);
_timerSimulacion = new DispatcherTimer();
- _timerSimulacion.Interval = TimeSpan.FromMilliseconds(20); // ajusta el intervalo según sea necesario
+ _timerSimulacion.Interval = TimeSpan.FromMilliseconds(16); // ajusta el intervalo según sea necesario
_timerSimulacion.Tick += OnTickSimulacion;
StartSimulationCommand = new RelayCommand(StartSimulation);
@@ -123,6 +124,11 @@ namespace CtrEditor
private void StartSimulation()
{
+ foreach (var objetoSimulable in ObjetosSimulables)
+ objetoSimulable.UpdateGeometryStart();
+
+ simulationManager.Debug_DrawInitialBodies();
+
_timerSimulacion.Start();
}
@@ -138,7 +144,7 @@ namespace CtrEditor
{
if (_plcViewModelData.IsConnected)
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
- objetoSimulable.UpdateGeometry();
+ objetoSimulable.UpdateGeometryStep();
}
simulationManager.Step((float)_timerSimulacion.Interval.TotalMilliseconds);
@@ -259,6 +265,7 @@ namespace CtrEditor
foreach (var obj in ObjetosSimulables)
{
obj.VisualRepresentation = null;
+ obj.simulationManager = null;
}
// Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter
var dataToSerialize = new SimulationData
@@ -328,7 +335,8 @@ namespace CtrEditor
// Asignar los datos al UserControl
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
- OnUserControlSelected?.Invoke(userControl);
+ OnUserControlSelected?.Invoke(userControl);
+
return true;
}
return false;
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 322df05..06d69fe 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -19,6 +19,7 @@ using Label = System.Windows.Controls.Label;
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
using TextBox = System.Windows.Controls.TextBox;
using UserControl = System.Windows.Controls.UserControl;
+//using OpenCvSharp;
namespace CtrEditor
@@ -62,6 +63,7 @@ namespace CtrEditor
//viewModel.TickSimulacion += MainViewModel_TickSimulacion;
viewModel.OnUserControlSelected += AgregarUserControl;
viewModel?.LoadInitialData(); // Carga la primera imagen por defecto una vez cargada la ventana principal
+ viewModel.simulationManager.DebugCanvas = ImagenEnTrabajoCanvas;
}
}
@@ -72,6 +74,7 @@ namespace CtrEditor
var NuevoOS = dataContainer.Datos;
if (!NuevoOS.Inicializado) // Aun no fue inicializado
{
+ Random rnd = new Random();
// Obtiene el factor de escala
var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform;
double scaleX = scaleTransform?.ScaleX ?? 1.0;
@@ -94,8 +97,8 @@ namespace CtrEditor
double topPixels = centerY - (userControl.ActualHeight / 2);
// Establece la posición del UserControl
- NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels);
- NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels);
+ NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels + (float)(rnd.NextDouble() - 0.5) );
+ NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels + (float)(rnd.NextDouble() - 0.5) );
NuevoOS.Inicializado = true;
}
@@ -117,7 +120,7 @@ namespace CtrEditor
// Añade el UserControl al Canvas
Canvas.SetZIndex(userControl, dataContainer.ZIndex());
- ImagenEnTrabajoCanvas.Children.Add(userControl);
+ ImagenEnTrabajoCanvas.Children.Add(userControl);
}
}
@@ -423,7 +426,7 @@ namespace CtrEditor
Source = selectedObject,
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus, // Actualizar solo al perder el foco
- Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"] // Usar el convertidor
+ //Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"] // Usar el convertidor
};
// Aplicar el convertidor solo a propiedades float
diff --git a/ObjetosSim/UserControlFactory.cs b/ObjetosSim/UserControlFactory.cs
index bdf0bf0..5b9597c 100644
--- a/ObjetosSim/UserControlFactory.cs
+++ b/ObjetosSim/UserControlFactory.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
+using CtrEditor.Simulacion;
namespace CtrEditor.ObjetosSim
{
@@ -20,8 +21,8 @@ namespace CtrEditor.ObjetosSim
return new ucGuia();
if (tipoObjeto == typeof(osTransporteGuias))
return new ucTransporteGuias();
- if (tipoObjeto == typeof(osTransporteCurva))
- return new ucTransporteCurva();
+ //if (tipoObjeto == typeof(osTransporteCurva))
+ // return new ucTransporteCurva();
if (tipoObjeto == typeof(osVMmotorSim ))
return new ucVMmotorSim();
@@ -40,8 +41,8 @@ namespace CtrEditor.ObjetosSim
return new osGuia();
if (tipoObjeto == typeof(osTransporteGuias))
return new osTransporteGuias();
- if (tipoObjeto == typeof(osTransporteCurva))
- return new osTransporteCurva();
+ //if (tipoObjeto == typeof(osTransporteCurva))
+ // return new osTransporteCurva();
if (tipoObjeto == typeof(osVMmotorSim))
return new osVMmotorSim();
@@ -62,14 +63,14 @@ namespace CtrEditor.ObjetosSim
return instance;
}
- public static void AssignDatos(UserControl userControl, osBase datos, SimulationManager simulationManager)
+ public static void AssignDatos(UserControl userControl, osBase datos, SimulationManagerFP simulationManager)
{
if (userControl is IDataContainer dataContainer)
{
dataContainer.Datos = datos;
userControl.DataContext = datos;
datos.VisualRepresentation = userControl;
- datos.ConnectSimManager(simulationManager);
+ datos.simulationManager = simulationManager;
}
}
}
diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs
index 37a3a68..bd35f5c 100644
--- a/ObjetosSim/osBase.cs
+++ b/ObjetosSim/osBase.cs
@@ -13,6 +13,10 @@ using System.Windows.Data;
using static System.Runtime.InteropServices.JavaScript.JSType;
using CtrEditor.Convertidores;
using CtrEditor.Siemens;
+using CtrEditor.Simulacion;
+using System.Windows.Media;
+using Microsoft.Xna.Framework;
+using FarseerPhysics.Dynamics;
namespace CtrEditor.ObjetosSim
{
@@ -23,7 +27,6 @@ namespace CtrEditor.ObjetosSim
{
string Nombre { get; }
- void ConnectSimManager(SimulationManager simulationManager);
void UpdateControl();
}
@@ -48,10 +51,11 @@ namespace CtrEditor.ObjetosSim
public abstract string Nombre { get; set; }
- public abstract void ConnectSimManager(SimulationManager simulationManager);
public abstract void UpdateControl();
- public abstract void UpdateGeometry();
+ public abstract void UpdateGeometryStart();
+ public abstract void UpdateGeometryStep();
public abstract void UpdatePLC(PLCModel plc);
+ public abstract void ucLoaded();
[JsonIgnore]
public UserControl? VisualRepresentation
@@ -59,6 +63,9 @@ namespace CtrEditor.ObjetosSim
get => _visualRepresentation;
set => _visualRepresentation = value;
}
+ [JsonIgnore]
+ public SimulationManagerFP simulationManager;
+
public void CanvasSetLeftinMeter(float left)
{
@@ -84,6 +91,91 @@ namespace CtrEditor.ObjetosSim
else return 0f;
}
+ public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect)
+ {
+ if (rect != null)
+ {
+ var _canvasLeft = CanvasGetLeftinMeter();
+ var _canvasTop = CanvasGetTopinMeter();
+
+ // Obtiene la transformada del objeto visual
+ GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation);
+
+ // Obtiene la posición absoluta
+ Point topLeft = transform.Transform(new Point(0, 0));
+ Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
+
+ return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop),
+ new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop));
+ }
+ else return (new Vector2(0, 0), new Vector2(0, 0));
+ }
+
+ public (Vector2 Start, Vector2 End) GetCenterLineVectors(System.Windows.Shapes.Rectangle rect)
+ {
+ if (rect == null)
+ return (new Vector2(0, 0), new Vector2(0, 0));
+
+ var _canvasLeft = CanvasGetLeftinMeter();
+ var _canvasTop = CanvasGetTopinMeter();
+
+ var transform = rect.TransformToAncestor(_visualRepresentation);
+
+ // Puntos en coordenadas locales del rectángulo no rotado
+ Point startLocal = new Point(0, rect.ActualHeight / 2);
+ Point endLocal = new Point(rect.ActualWidth, rect.ActualHeight / 2);
+
+ // Transformar estos puntos al sistema de coordenadas del ancestro
+ Point transformedStart = transform.Transform(startLocal);
+ Point transformedEnd = transform.Transform(endLocal);
+
+ // Convierte a unidades de Farseer (metros en este caso)
+ Vector2 start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
+ Vector2 end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
+
+ return (start, end);
+ }
+
+
+ public Vector2 GetRectangleCenter(System.Windows.Shapes.Rectangle wpfRect)
+ {
+ var coords = GetRectangleCoordinatesInMeter(wpfRect);
+
+ Vector2 topLeft = coords.TopLeft;
+ Vector2 bottomRight = coords.BottomRight;
+
+ // Calcular el centro, ancho y alto en metros
+ return new Vector2((topLeft.X + bottomRight.X) / 2, (topLeft.Y + bottomRight.Y) / 2);
+ }
+
+ public void UpdateRectangle(simRectangle simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
+ {
+ if (simRect != null)
+ simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
+ }
+
+ public simRectangle AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
+ {
+ return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
+ }
+
+ public void UpdateOrCreateLine(simLine simGuia, System.Windows.Shapes.Rectangle wpfRect)
+ {
+ if (simGuia != null)
+ {
+ var coords = GetCenterLineVectors(wpfRect);
+
+ // Crear o actualizar simRectangle
+ simGuia.Create( coords.Start,coords.End); // asumiendo que el ángulo inicial es 0
+ }
+ }
+
+ public simLine AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect)
+ {
+ var coords = GetCenterLineVectors(wpfRect);
+ return simulationManager.AddLine(coords.Start, coords.End);
+ }
+
public event PropertyChangedEventHandler PropertyChanged;
@@ -93,7 +185,4 @@ namespace CtrEditor.ObjetosSim
}
}
-
-
-
}
diff --git a/ObjetosSim/ucBotella.xaml.cs b/ObjetosSim/ucBotella.xaml.cs
index 0516460..97a1482 100644
--- a/ObjetosSim/ucBotella.xaml.cs
+++ b/ObjetosSim/ucBotella.xaml.cs
@@ -12,9 +12,11 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
-using System.Numerics;
+using Microsoft.Xna.Framework;
using CtrEditor.Convertidores;
using CtrEditor.Siemens;
+using CtrEditor.Simulacion;
+using Newtonsoft.Json.Linq;
namespace CtrEditor.ObjetosSim
{
@@ -25,61 +27,88 @@ namespace CtrEditor.ObjetosSim
public class osBotella : osBase
{
- private Circle Geometria = new Circle();
+ private float _diametro;
+ private float _mass;
+ private Vector2 _centro = new Vector2(); // Centro
+ private string _nombre = "Botella";
+ private simCircle Simulacion_Botella;
// Otros datos y métodos relevantes para la simulación
- private string _nombre = "Botella";
public float Diametro {
- get => Geometria.Diameter;
+ get => _diametro;
set
{
- Geometria.Diameter = value;
+ _diametro = value;
+ Simulacion_Botella?.SetDiameter(Diametro);
OnPropertyChanged(nameof(Diametro));
}
}
public float Mass {
- get => Geometria.Mass;
+ get => _mass;
set
{
- Geometria.Mass = value;
+ _mass = value;
+ Simulacion_Botella?.SetMass(value);
OnPropertyChanged(nameof(Mass));
}
}
- public float Overlap
- {
- get => Geometria.Overlap;
- set
- {
- Geometria.Overlap = value;
- OnPropertyChanged(nameof(Overlap));
- }
- }
-
public override float Left
{
- get => Geometria.Left;
+ get => _centro.X-Diametro/2;
set
{
- Geometria.Left = value;
+ _centro.X = value+Diametro/2;
CanvasSetLeftinMeter(value);
OnPropertyChanged(nameof(Left));
}
}
public override float Top
{
- get => Geometria.Top;
+ get => _centro.Y - Diametro / 2;
set
{
- Geometria.Top = value;
+ _centro.Y = value + Diametro / 2;
CanvasSetTopinMeter(value);
OnPropertyChanged(nameof(Top));
}
}
+ public float CenterX
+ {
+ get => _centro.X;
+ set
+ {
+ _centro.X = value;
+ CanvasSetLeftinMeter(Left);
+ OnPropertyChanged(nameof(CenterX));
+ OnPropertyChanged(nameof(Left));
+ }
+ }
+ public float CenterY
+ {
+ get => _centro.Y;
+ set
+ {
+ _centro.Y = value;
+ CanvasSetTopinMeter(Top);
+ OnPropertyChanged(nameof(CenterY));
+ OnPropertyChanged(nameof(Top));
+ }
+ }
+
+ private void ActualizarGeometrias()
+ {
+ if (Simulacion_Botella != null)
+ {
+ Simulacion_Botella.SetDiameter(Diametro);
+ Simulacion_Botella.SetPosition(CenterX, CenterY);
+ }
+ }
+
public override string Nombre
{
get => _nombre;
@@ -96,25 +125,34 @@ namespace CtrEditor.ObjetosSim
public osBotella()
{
Diametro = 0.10f;
+ Mass = 1;
}
- public override void ConnectSimManager(SimulationManager simulationManager)
- {
- simulationManager.circles.Add(Geometria);
- }
- public override void UpdateGeometry()
+ public override void UpdateGeometryStart()
{
// Se llama antes de la simulacion
-
+ ActualizarGeometrias();
}
+ public override void UpdateGeometryStep()
+ {
+ // Se llama antes de la simulacion
+ ActualizarGeometrias();
+ }
+
public override void UpdatePLC(PLCModel plc) { }
public override void UpdateControl()
{
- Top = Geometria.Top;
- Left = Geometria.Left;
- Overlap = Geometria.Overlap;
+ CenterX = Simulacion_Botella.CenterX;
+ CenterY = Simulacion_Botella.CenterY;
}
+ public override void ucLoaded()
+ {
+ // El UserControl ya se ha cargado y podemos obtener las coordenadas para
+ // crear el objeto de simulacion
+ Simulacion_Botella = simulationManager.AddCircle(Diametro, _centro, Mass);
+ }
+
}
public partial class ucBotella : UserControl, IDataContainer
@@ -124,6 +162,11 @@ namespace CtrEditor.ObjetosSim
public ucBotella()
{
InitializeComponent();
+ this.Loaded += OnLoaded;
+ }
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ Datos?.ucLoaded();
}
public void Resize(float width, float height) { }
public void Move(float LeftPixels, float TopPixels)
diff --git a/ObjetosSim/ucGuia.xaml b/ObjetosSim/ucGuia.xaml
index f839964..b109b2e 100644
--- a/ObjetosSim/ucGuia.xaml
+++ b/ObjetosSim/ucGuia.xaml
@@ -11,7 +11,7 @@