diff --git a/Convertidores/Converters.cs b/Convertidores/Converters.cs index 46ff7a0..d5a34b1 100644 --- a/Convertidores/Converters.cs +++ b/Convertidores/Converters.cs @@ -10,6 +10,26 @@ using System.Windows.Media; namespace CtrEditor.Convertidores { + + public class SpeedAndWidthToDurationConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 2 && values[0] is double speed && values[1] is double width && speed > 0) + { + // Convert speed (meters per minute) to duration (seconds) + double durationInSeconds = (width * 60) / speed; + return new Duration(TimeSpan.FromSeconds(durationInSeconds)); + } + return DependencyProperty.UnsetValue; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } + public class HalfWidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/MainViewModel.cs b/MainViewModel.cs index df0ca61..ead3a47 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -591,6 +591,135 @@ namespace CtrEditor catch { /* Consider logging the error or handling it appropriately */ } } + // Se cargan los datos de cada UserControl en el StackPanel + public void CargarPropiedadesosDatos(osBase selectedObject, StackPanel PanelEdicion, ResourceDictionary Resources) + { + PanelEdicion.Children.Clear(); + var properties = selectedObject.GetType().GetProperties(); + + foreach (var property in properties) + { + if (Attribute.IsDefined(property, typeof(HiddenAttribute))) + continue; + if (property.Name.EndsWith("_oculto")) + continue; + + var grid = new Grid(); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); + grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); + + var label = new Label + { + Content = property.Name.Replace("_", " ") + ":", + Margin = new Thickness(0, 0, 5, 0), + VerticalAlignment = VerticalAlignment.Center + }; + + if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int)) + { + var textBox = new TextBox + { + Margin = new Thickness(0), + MinWidth = 200, + VerticalContentAlignment = VerticalAlignment.Center + }; + + var binding = new Binding(property.Name) + { + Source = selectedObject, + Mode = BindingMode.TwoWay, + UpdateSourceTrigger = UpdateSourceTrigger.LostFocus + }; + + if (property.PropertyType == typeof(float)) + { + binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"]; + } + + textBox.SetBinding(TextBox.TextProperty, binding); + + Grid.SetColumn(label, 0); + Grid.SetColumn(textBox, 1); + + grid.Children.Add(label); + grid.Children.Add(textBox); + } + else if (property.PropertyType == typeof(bool)) + { + var checkBox = new CheckBox + { + Margin = new Thickness(5, 0, 0, 0), + VerticalAlignment = VerticalAlignment.Center + }; + + var binding = new Binding(property.Name) + { + Source = selectedObject, + Mode = BindingMode.TwoWay + }; + + checkBox.SetBinding(CheckBox.IsCheckedProperty, binding); + + Grid.SetColumn(label, 0); + Grid.SetColumn(checkBox, 1); + + grid.Children.Add(label); + grid.Children.Add(checkBox); + } + else if (property.PropertyType == typeof(Brush)) + { + var listBox = new ListBox + { + ItemsSource = new List { "Rojo", "Azul", "Negro", "Verde", "Gris" }, + Margin = new Thickness(0), + MinWidth = 200 + }; + + listBox.SelectionChanged += (sender, e) => + { + if (listBox.SelectedItem != null) + { + switch (listBox.SelectedItem.ToString()) + { + case "Rojo": + property.SetValue(selectedObject, Brushes.Red); + break; + case "Azul": + property.SetValue(selectedObject, Brushes.Blue); + break; + case "Negro": + property.SetValue(selectedObject, Brushes.Black); + break; + case "Verde": + property.SetValue(selectedObject, Brushes.Green); + break; + case "Gris": + property.SetValue(selectedObject, Brushes.Gray); + break; + } + } + }; + + var binding = new Binding(property.Name) + { + Source = selectedObject, + Mode = BindingMode.TwoWay, + Converter = new BrushToColorNameConverter() + }; + + listBox.SetBinding(ListBox.SelectedItemProperty, binding); + + Grid.SetColumn(label, 0); + Grid.SetColumn(listBox, 1); + + grid.Children.Add(label); + grid.Children.Add(listBox); + } + + PanelEdicion.Children.Add(grid); + } + } + // Implementación de INotifyPropertyChanged... diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 4e29900..b2e4eeb 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -276,17 +276,29 @@ namespace CtrEditor // Calcular la diferencia en la posición X desde el punto de inicio double widthChange = currentPosition.X - _startPointUserControl.X; + // Calcular la diferencia en la posición Y desde el punto de inicio + double heightChange = currentPosition.Y - _startPointUserControl.Y; + // Actualizar el ancho del control double newWidth = Math.Max(control.ActualWidth + widthChange, control.MinWidth); - control.Width = newWidth; // Asegurar que no sea menor que el mínimo + + // Actualizar la altura del control + double newHeight = Math.Max(control.ActualHeight + heightChange, control.MinHeight); + + // Asegurar que el nuevo tamaño no sea menor que los mínimos + control.Width = newWidth; + control.Height = newHeight; if (control is IDataContainer dataContainer) - dataContainer.Resize((float)newWidth, 0); + { + dataContainer.Resize((float)newWidth, (float)newHeight); + } // Actualizar el punto de inicio para el próximo evento de movimiento _startPointUserControl = currentPosition; } + private void UserControl_MouseEnter(object sender, MouseEventArgs e) { if (sender is UserControl userControl) @@ -413,133 +425,10 @@ namespace CtrEditor private void CargarPropiedadesosDatos(osBase selectedObject) { - PanelEdicion.Children.Clear(); - var properties = selectedObject.GetType().GetProperties(); - - foreach (var property in properties) - { - if (Attribute.IsDefined(property, typeof(HiddenAttribute))) - { - continue; - } - - var grid = new Grid(); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); - - var label = new Label - { - Content = property.Name + ":", - Margin = new Thickness(0, 0, 5, 0), - VerticalAlignment = VerticalAlignment.Center - }; - - if (property.PropertyType == typeof(float) || property.PropertyType == typeof(string) || property.PropertyType == typeof(int)) - { - var textBox = new TextBox - { - Margin = new Thickness(0), - MinWidth = 200, - VerticalContentAlignment = VerticalAlignment.Center - }; - - var binding = new Binding(property.Name) - { - Source = selectedObject, - Mode = BindingMode.TwoWay, - UpdateSourceTrigger = UpdateSourceTrigger.LostFocus - }; - - if (property.PropertyType == typeof(float)) - { - binding.Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"]; - } - - textBox.SetBinding(TextBox.TextProperty, binding); - - Grid.SetColumn(label, 0); - Grid.SetColumn(textBox, 1); - - grid.Children.Add(label); - grid.Children.Add(textBox); - } - else if (property.PropertyType == typeof(bool)) - { - var checkBox = new CheckBox - { - Margin = new Thickness(5, 0, 0, 0), - VerticalAlignment = VerticalAlignment.Center - }; - - var binding = new Binding(property.Name) - { - Source = selectedObject, - Mode = BindingMode.TwoWay - }; - - checkBox.SetBinding(CheckBox.IsCheckedProperty, binding); - - Grid.SetColumn(label, 0); - Grid.SetColumn(checkBox, 1); - - grid.Children.Add(label); - grid.Children.Add(checkBox); - } - else if (property.PropertyType == typeof(Brush)) - { - var listBox = new ListBox - { - ItemsSource = new List { "Rojo", "Azul", "Negro", "Verde", "Gris" }, - Margin = new Thickness(0), - MinWidth = 200 - }; - - listBox.SelectionChanged += (sender, e) => - { - if (listBox.SelectedItem != null) - { - switch (listBox.SelectedItem.ToString()) - { - case "Rojo": - property.SetValue(selectedObject, Brushes.Red); - break; - case "Azul": - property.SetValue(selectedObject, Brushes.Blue); - break; - case "Negro": - property.SetValue(selectedObject, Brushes.Black); - break; - case "Verde": - property.SetValue(selectedObject, Brushes.Green); - break; - case "Gris": - property.SetValue(selectedObject, Brushes.Gray); - break; - } - } - }; - - var binding = new Binding(property.Name) - { - Source = selectedObject, - Mode = BindingMode.TwoWay, - Converter = new BrushToColorNameConverter() - }; - - listBox.SetBinding(ListBox.SelectedItemProperty, binding); - - Grid.SetColumn(label, 0); - Grid.SetColumn(listBox, 1); - - grid.Children.Add(label); - grid.Children.Add(listBox); - } - - PanelEdicion.Children.Add(grid); - } + if (DataContext is MainViewModel viewModel) + viewModel.CargarPropiedadesosDatos(selectedObject, PanelEdicion, Resources); } - private void MainWindow_Closed(object sender, EventArgs e) { if (DataContext is MainViewModel viewModel) diff --git a/ObjetosSim/UserControls/ucGuia.xaml b/ObjetosSim/UserControls/ucGuia.xaml index b109b2e..14f0131 100644 --- a/ObjetosSim/UserControls/ucGuia.xaml +++ b/ObjetosSim/UserControls/ucGuia.xaml @@ -4,12 +4,17 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" + xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" xmlns:convert="clr-namespace:CtrEditor.Convertidores"> + + + + diff --git a/ObjetosSim/UserControls/ucGuia.xaml.cs b/ObjetosSim/UserControls/ucGuia.xaml.cs index e5f3cd2..57ef364 100644 --- a/ObjetosSim/UserControls/ucGuia.xaml.cs +++ b/ObjetosSim/UserControls/ucGuia.xaml.cs @@ -12,6 +12,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using CommunityToolkit.Mvvm.ComponentModel; using CtrEditor.Convertidores; using CtrEditor.Siemens; using CtrEditor.Simulacion; @@ -24,88 +25,54 @@ namespace CtrEditor.ObjetosSim /// /// Interaction logic for ucGuia.xaml /// - public class osGuia : osBase, IosBase + public partial class osGuia : osBase, IosBase { - private float _ancho; - private float _altoGuia; - private float _left; - private float _top; - private float _angulo; - private string _nombre = "Guia"; - - private simGuia Simulation_Guia; + private simGuia SimGeometria; public static string NombreClase() { return "Guia"; } - public override float Left - { - get => _left; - set - { - _left = value; - CanvasSetLeftinMeter(value); - OnPropertyChanged(nameof(Left)); - } - } - public override float Top - { - get => _top; - set - { - _top = value; - CanvasSetTopinMeter(value); - OnPropertyChanged(nameof(Top)); - } - } - - public float Ancho - { - get => _ancho; - set - { - _ancho = value; - OnPropertyChanged(nameof(Ancho)); - } - } - public float AltoGuia - { - get => _altoGuia; - set - { - _altoGuia = value; - OnPropertyChanged(nameof(AltoGuia)); - } - } - - public float Angulo - { - get => _angulo; - set - { - _angulo = value; - OnPropertyChanged(nameof(Angulo)); - } - } - + private string nombre = "Guia"; public override string Nombre { - get => _nombre; + get => nombre; + set => SetProperty(ref nombre, value); + } + private float left; + public override float Left + { + get => left; set { - if (_nombre != value) - { - _nombre = value; - OnPropertyChanged(nameof(Nombre)); - } + CanvasSetLeftinMeter(value); + SetProperty(ref left, value); } } + private float top; + public override float Top + { + get => top; + set + { + CanvasSetTopinMeter(value); + SetProperty(ref top, value); + } + } + + [ObservableProperty] + public float ancho; + + [ObservableProperty] + public float altoGuia; + + [ObservableProperty] + public float angulo; private void ActualizarGeometrias() { if (_visualRepresentation is ucGuia uc) - UpdateOrCreateLine(Simulation_Guia, uc.Guia); + UpdateOrCreateLine(SimGeometria, uc.Guia); } public osGuia() @@ -133,13 +100,13 @@ namespace CtrEditor.ObjetosSim ActualizarLeftTop(); if (_visualRepresentation is ucGuia uc) - Simulation_Guia = AddLine(simulationManager, uc.Guia); + SimGeometria = AddLine(simulationManager, uc.Guia); } public override void ucUnLoaded() { // El UserControl se esta eliminando // eliminar el objeto de simulacion - simulationManager.Remove(Simulation_Guia); + simulationManager?.Remove(SimGeometria); } diff --git a/ObjetosSim/UserControls/ucTransporteCurva.xaml b/ObjetosSim/UserControls/ucTransporteCurva.xaml index 428323b..d2c7be4 100644 --- a/ObjetosSim/UserControls/ucTransporteCurva.xaml +++ b/ObjetosSim/UserControls/ucTransporteCurva.xaml @@ -5,13 +5,19 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:localuc="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:convert="clr-namespace:CtrEditor.Convertidores" + xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" mc:Ignorable="d"> - - + + + + + + + diff --git a/ObjetosSim/UserControls/ucTransporteCurva.xaml.cs b/ObjetosSim/UserControls/ucTransporteCurva.xaml.cs index 91f9afd..7314f9f 100644 --- a/ObjetosSim/UserControls/ucTransporteCurva.xaml.cs +++ b/ObjetosSim/UserControls/ucTransporteCurva.xaml.cs @@ -19,37 +19,23 @@ namespace CtrEditor.ObjetosSim private float tiempoRampa; private bool esMarcha; - private float _velocidadActual; + private float _velocidadActual; private osBase _osMotor = null; private string _motor; - private simTransporte Simulation_Transporte; + private simCurve Simulation_TransporteCurva; public static string NombreClase() { return "Transporte Curva 90"; } - - private float angulo; - public float Angulo + private string nombre = "Transporte Curva 90"; + public override string Nombre { - get => angulo; - set - { - ActualizarGeometrias(); - SetProperty(ref angulo, value); - } + get => nombre; + set => SetProperty(ref nombre, value); } - [ObservableProperty] - private float radioExterno; - - [ObservableProperty] - private float radioInterno; - - [ObservableProperty] - private string motor; - private float left; public override float Left { @@ -72,11 +58,25 @@ namespace CtrEditor.ObjetosSim } [ObservableProperty] - public float ancho; + private float radioExterno; + [ObservableProperty] + private float radioInterno; + [ObservableProperty] + private string motor; [ObservableProperty] - public float alto; + [NotifyPropertyChangedFor(nameof(AnguloFinal))] + public float angulo; + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(AnguloFinal))] + private float arco_en_grados; + + [Hidden] + public float AnguloFinal + { + get => Angulo+Arco_en_grados; + } public float VelocidadActual { @@ -84,24 +84,17 @@ namespace CtrEditor.ObjetosSim set { _velocidadActual = value; - Simulation_Transporte?.SetSpeed(value); + Simulation_TransporteCurva?.SetSpeed(value); OnPropertyChanged(nameof(VelocidadActual)); } } - private string nombre = "Transporte Curva 90"; - public override string Nombre - { - get => nombre; - set => SetProperty(ref nombre, value); - } - private void ActualizarGeometrias() { if (_visualRepresentation is ucTransporteCurva uc) { - //UpdateRectangle(Simulation_Transporte, uc.Transporte, Alto, Ancho, Angulo); - Simulation_Transporte.Speed = VelocidadActual; + UpdateCurve(Simulation_TransporteCurva, RadioInterno, RadioExterno, Angulo, Angulo+Arco_en_grados); + Simulation_TransporteCurva.Speed = VelocidadActual; } } @@ -112,10 +105,9 @@ namespace CtrEditor.ObjetosSim public osTransporteCurva() { - Ancho = 1; - Alto = 0.10f; - RadioExterno = 2; + RadioExterno = 1.3f; RadioInterno = 1; + Arco_en_grados = 90; } public override void UpdateGeometryStart() @@ -146,14 +138,16 @@ namespace CtrEditor.ObjetosSim // crear el objeto de simulacion ActualizarLeftTop(); - //if (_visualRepresentation is ucTransporteCurva uc) - // Simulation_Transporte = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo); + if (_visualRepresentation is ucTransporteCurva uc) + Simulation_TransporteCurva = AddCurve(RadioInterno,RadioExterno, Angulo, Angulo + Arco_en_grados); + + // AddCurve(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position) } public override void ucUnLoaded() { // El UserControl se esta eliminando // eliminar el objeto de simulacion - simulationManager.Remove(Simulation_Transporte); + simulationManager?.Remove(Simulation_TransporteCurva); } } @@ -176,10 +170,16 @@ namespace CtrEditor.ObjetosSim { Datos?.ucUnLoaded(); } - public void Resize(float width, float height) + public void Resize(float RadioExterno, float RadioInterno) { if (Datos is osTransporteCurva datos) - datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width); + { + if (RadioExterno > RadioInterno && RadioExterno > 0 && RadioInterno >= 0) + { + datos.RadioExterno = PixelToMeter.Instance.calc.PixelsToMeters(RadioExterno); + datos.RadioInterno = PixelToMeter.Instance.calc.PixelsToMeters(RadioInterno); + } + } } public void Move(float LeftPixels, float TopPixels) { diff --git a/ObjetosSim/UserControls/ucTransporteTTop.xaml b/ObjetosSim/UserControls/ucTransporteTTop.xaml index f9493e0..9d7416f 100644 --- a/ObjetosSim/UserControls/ucTransporteTTop.xaml +++ b/ObjetosSim/UserControls/ucTransporteTTop.xaml @@ -4,19 +4,62 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" - xmlns:convert="clr-namespace:CtrEditor.Convertidores"> - + xmlns:vm="clr-namespace:CtrEditor.ObjetosSim" + xmlns:convert="clr-namespace:CtrEditor.Convertidores" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"> + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + Forever + + + + + + + - - diff --git a/ObjetosSim/UserControls/ucTransporteTTop.xaml.cs b/ObjetosSim/UserControls/ucTransporteTTop.xaml.cs index 994ddb1..7be8c88 100644 --- a/ObjetosSim/UserControls/ucTransporteTTop.xaml.cs +++ b/ObjetosSim/UserControls/ucTransporteTTop.xaml.cs @@ -1,5 +1,8 @@ using System.Windows; using System.Windows.Controls; +using System.Windows.Media.Animation; +using System.Windows.Media; +using CommunityToolkit.Mvvm.ComponentModel; using CtrEditor.Convertidores; using CtrEditor.Siemens; using CtrEditor.Simulacion; @@ -12,23 +15,9 @@ namespace CtrEditor.ObjetosSim /// /// - public class osTransporteTTop : osBase, IosBase + public partial class osTransporteTTop : osBase, IosBase { - private string _nombre = "Transporte TTOP"; - - private float frictionCoefficient; - private float velMax50hz; // en metros por minuto - private float tiempoRampa; - private bool esMarcha; - - private float _ancho; - private float _alto; - private float _left; - private float _top; - private float _angulo; - private float _velocidadActual; private osBase _osMotor = null; - private string _motor; private simTransporte Simulation_Transporte; @@ -36,90 +25,62 @@ namespace CtrEditor.ObjetosSim { return "Transporte"; } - public string Motor - { - get => _motor; - set - { - if (_motor != value) - { - _motor = value; - OnPropertyChanged(nameof(Motor)); - } - } - } - public override float Left - { - get => _left; - set - { - _left = value; - CanvasSetLeftinMeter(value); - OnPropertyChanged(nameof(Left)); - } - } - public override float Top - { - get => _top; - set - { - _top = value; - CanvasSetTopinMeter(value); - OnPropertyChanged(nameof(Top)); - } - } - - public float Ancho - { - get => _ancho; - set - { - _ancho = value; - OnPropertyChanged(nameof(Ancho)); - } - } - public float Alto - { - get => _alto; - set - { - _alto = value; - OnPropertyChanged(nameof(Alto)); - } - } - - public float Angulo - { - get => _angulo; - set - { - _angulo = value; - OnPropertyChanged(nameof(Angulo)); - } - } - - public float VelocidadActual - { - get => _velocidadActual; - set { - _velocidadActual = value; - Simulation_Transporte?.SetSpeed(value); - OnPropertyChanged(nameof(VelocidadActual)); - } - } - + private string nombre = "Transporte TTOP"; public override string Nombre { - get => _nombre; + get => nombre; + set => SetProperty(ref nombre, value); + } + + private float left; + public override float Left + { + get => left; set { - if (_nombre != value) - { - _nombre = value; - OnPropertyChanged(nameof(Nombre)); - } + CanvasSetLeftinMeter(value); + SetProperty(ref left, value); } } + private float top; + public override float Top + { + get => top; + set + { + CanvasSetTopinMeter(value); + SetProperty(ref top, value); + } + } + + private float velocidadActual; + public float VelocidadActual + { + get => velocidadActual; + set + { + velocidadActual = value; + Simulation_Transporte?.SetSpeed(value); + SetProperty(ref velocidadActual, value); + } + } + + [ObservableProperty] + public string motor; + [ObservableProperty] + public float ancho; + [ObservableProperty] + public float alto; + [ObservableProperty] + public float angulo; + [ObservableProperty] + public float frictionCoefficient; + [ObservableProperty] + public float velMax50hz; + [ObservableProperty] + public float tiempoRampa; + [ObservableProperty] + public bool esMarcha; private void ActualizarGeometrias() { @@ -130,10 +91,6 @@ namespace CtrEditor.ObjetosSim } } - public float FrictionCoefficient { get => frictionCoefficient; set => frictionCoefficient = value; } - public float VelMax50hz { get => velMax50hz; set => velMax50hz = value; } - public float TiempoRampa { get => tiempoRampa; set => tiempoRampa = value; } - public bool EsMarcha { get => esMarcha; set => esMarcha = value; } public osTransporteTTop() { @@ -157,7 +114,7 @@ namespace CtrEditor.ObjetosSim VelocidadActual = motor.Velocidad; } else - _osMotor = ObtenerLink(_motor, typeof(osVMmotorSim)); + _osMotor = ObtenerLink(Motor, typeof(osVMmotorSim)); } public override void UpdateControl(int elapsedMilliseconds) diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index d90a94c..91edf45 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -250,6 +250,18 @@ namespace CtrEditor.ObjetosSim return (start, end); } + public Vector2 GetCurveCenterInMeter(float RadioExterno) + { + var _canvasLeft = CanvasGetLeftinMeter(); + var _canvasTop = CanvasGetTopinMeter(); + + // El centro del Canvas + double centerX = RadioExterno + _canvasLeft; + double centerY = RadioExterno + _canvasTop; + + // Convertir a Vector2 + return new Vector2((float)centerX, (float)centerY); + } public Vector2 GetRectangleCenter(System.Windows.Shapes.Rectangle wpfRect) { @@ -262,6 +274,8 @@ namespace CtrEditor.ObjetosSim return new Vector2((topLeft.X + bottomRight.X) / 2, (topLeft.Y + bottomRight.Y) / 2); } + + public void UpdateRectangle(simTransporte simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { if (simRect != null) @@ -274,6 +288,16 @@ namespace CtrEditor.ObjetosSim simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } + public void UpdateCurve(simCurve curva,float RadioInterno, float RadioExterno, float startAngle, float endAngle) + { + curva.Create(RadioInterno, RadioExterno, startAngle, endAngle, GetCurveCenterInMeter(RadioExterno)); + } + + public simCurve AddCurve(float RadioInterno, float RadioExterno, float startAngle, float endAngle) + { + return simulationManager.AddCurve(RadioInterno, RadioExterno, startAngle, endAngle, GetCurveCenterInMeter(RadioExterno)); + } + public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); diff --git a/Simulacion/FPhysics.cs b/Simulacion/FPhysics.cs index 7d6aa7a..011d7a1 100644 --- a/Simulacion/FPhysics.cs +++ b/Simulacion/FPhysics.cs @@ -14,6 +14,7 @@ using System.Windows; using System.Diagnostics; using FarseerPhysics.Dynamics.Joints; +using CtrEditor.ObjetosSim; namespace CtrEditor.Simulacion { @@ -42,6 +43,7 @@ namespace CtrEditor.Simulacion 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) { @@ -53,12 +55,19 @@ namespace CtrEditor.Simulacion Create(position); } - private void Create(Vector2 position) + public void Create(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position) { - if (Body != null) - { - _world.RemoveBody(Body); - } + if (_world == null) return; + _innerRadius = innerRadius; + _outerRadius = outerRadius; + _startAngle = MathHelper.ToRadians(startAngle); + _endAngle = 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); @@ -74,6 +83,11 @@ namespace CtrEditor.Simulacion Body.UserData = this; } + public void SetSpeed(float speed) + { + Speed = speed; + } + private List CreateCurveVertices(float innerRadius, float outerRadius, float startAngle, float endAngle) { List verticesList = new List(); @@ -97,24 +111,24 @@ namespace CtrEditor.Simulacion return verticesList; } - public void ApplyCurveEffect(simBotella bottle) + public void ApplyCurveEffect(Fixture bottle) { - // Crear un joint para mantener la botella en la curva - RevoluteJoint joint = new RevoluteJoint(bottle.Body, Body, Body.Position, true) - { - CollideConnected = false - }; - _world.AddJoint(joint); + Vector2 centerToBottle = bottle.Body.Position - Body.Position; + float distanceToCenter = centerToBottle.Length(); - bottle.CurrentJoint = joint; - } - - public void RemoveCurveEffect(simBotella bottle) - { - if (bottle.CurrentJoint != null) + if (distanceToCenter >= _innerRadius && distanceToCenter <= _outerRadius) { - _world.RemoveJoint(bottle.CurrentJoint); - bottle.CurrentJoint = null; + // 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; } } } @@ -261,7 +275,6 @@ namespace CtrEditor.Simulacion private float _radius; private float _mass; public bool Descartar = false; - public RevoluteJoint CurrentJoint { get; set; } public simBotella(World world, float diameter, Vector2 position, float mass) { @@ -341,7 +354,7 @@ namespace CtrEditor.Simulacion } else if (fixtureB.Body.UserData is simCurve curve) { - curve.ApplyCurveEffect(this); + curve.ApplyCurveEffect(fixtureA); return true; // No aplicar respuestas físicas } else if (fixtureB.Body.UserData is simDescarte) @@ -351,42 +364,40 @@ namespace CtrEditor.Simulacion } else if (fixtureB.Body.UserData is simTransporte) { simTransporte conveyor = fixtureB.Body.UserData as simTransporte; - 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; + if ( conveyor.Speed != 0 ) { - // 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); + CircleShape circleShape = fixtureA.Shape as CircleShape; + PolygonShape polygonShape = fixtureB.Shape as PolygonShape; - 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); + // 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 = InterseccionCirculoRectangulo.CalcularSuperficieCompartida(vertices, centroCirculo, radio); + + // Aplicar el efecto del transportador usando el porcentaje calculado + ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido); } - - // Calcular el porcentaje de la superficie compartida - float porcentajeCompartido = InterseccionCirculoRectangulo.CalcularSuperficieCompartida(vertices, centroCirculo, radio); - - // Aplicar el efecto del transportador usando el porcentaje calculado - ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido); - return true; // No aplicar respuestas físicas } return true; // No aplicar respuestas físicas } - private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB) - { - - } - private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido) { float speedMetersPerSecond = conveyor.Speed / 60.0f; @@ -442,6 +453,13 @@ namespace CtrEditor.Simulacion } } + 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);