Agregando simulacion a los transportes

This commit is contained in:
Miguel 2024-05-22 11:19:31 +02:00
parent f090722de0
commit 260362dc24
11 changed files with 448 additions and 390 deletions

View File

@ -10,6 +10,26 @@ using System.Windows.Media;
namespace CtrEditor.Convertidores 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 class HalfWidthConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

View File

@ -591,6 +591,135 @@ namespace CtrEditor
catch { /* Consider logging the error or handling it appropriately */ } 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<string> { "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... // Implementación de INotifyPropertyChanged...

View File

@ -276,17 +276,29 @@ namespace CtrEditor
// Calcular la diferencia en la posición X desde el punto de inicio // Calcular la diferencia en la posición X desde el punto de inicio
double widthChange = currentPosition.X - _startPointUserControl.X; 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 // Actualizar el ancho del control
double newWidth = Math.Max(control.ActualWidth + widthChange, control.MinWidth); 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) 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 // Actualizar el punto de inicio para el próximo evento de movimiento
_startPointUserControl = currentPosition; _startPointUserControl = currentPosition;
} }
private void UserControl_MouseEnter(object sender, MouseEventArgs e) private void UserControl_MouseEnter(object sender, MouseEventArgs e)
{ {
if (sender is UserControl userControl) if (sender is UserControl userControl)
@ -413,133 +425,10 @@ namespace CtrEditor
private void CargarPropiedadesosDatos(osBase selectedObject) private void CargarPropiedadesosDatos(osBase selectedObject)
{ {
PanelEdicion.Children.Clear(); if (DataContext is MainViewModel viewModel)
var properties = selectedObject.GetType().GetProperties(); viewModel.CargarPropiedadesosDatos(selectedObject, PanelEdicion, Resources);
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<string> { "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);
}
}
private void MainWindow_Closed(object sender, EventArgs e) private void MainWindow_Closed(object sender, EventArgs e)
{ {
if (DataContext is MainViewModel viewModel) if (DataContext is MainViewModel viewModel)

View File

@ -4,12 +4,17 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" mc:Ignorable="d"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
xmlns:convert="clr-namespace:CtrEditor.Convertidores"> xmlns:convert="clr-namespace:CtrEditor.Convertidores">
<UserControl.Resources> <UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/> <convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources> </UserControl.Resources>
<UserControl.DataContext>
<vm:osGuia/>
</UserControl.DataContext>
<Canvas> <Canvas>
<Rectangle x:Name="Guia" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue"> <Rectangle x:Name="Guia" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue">
<Rectangle.RenderTransform> <Rectangle.RenderTransform>

View File

@ -12,6 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.Siemens; using CtrEditor.Siemens;
using CtrEditor.Simulacion; using CtrEditor.Simulacion;
@ -24,88 +25,54 @@ namespace CtrEditor.ObjetosSim
/// <summary> /// <summary>
/// Interaction logic for ucGuia.xaml /// Interaction logic for ucGuia.xaml
/// </summary> /// </summary>
public class osGuia : osBase, IosBase public partial class osGuia : osBase, IosBase
{ {
private float _ancho; private simGuia SimGeometria;
private float _altoGuia;
private float _left;
private float _top;
private float _angulo;
private string _nombre = "Guia";
private simGuia Simulation_Guia;
public static string NombreClase() public static string NombreClase()
{ {
return "Guia"; return "Guia";
} }
public override float Left private string nombre = "Guia";
{
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));
}
}
public override string Nombre public override string Nombre
{ {
get => _nombre; get => nombre;
set => SetProperty(ref nombre, value);
}
private float left;
public override float Left
{
get => left;
set set
{ {
if (_nombre != value) CanvasSetLeftinMeter(value);
SetProperty(ref left, value);
}
}
private float top;
public override float Top
{ {
_nombre = value; get => top;
OnPropertyChanged(nameof(Nombre)); set
} {
CanvasSetTopinMeter(value);
SetProperty(ref top, value);
} }
} }
[ObservableProperty]
public float ancho;
[ObservableProperty]
public float altoGuia;
[ObservableProperty]
public float angulo;
private void ActualizarGeometrias() private void ActualizarGeometrias()
{ {
if (_visualRepresentation is ucGuia uc) if (_visualRepresentation is ucGuia uc)
UpdateOrCreateLine(Simulation_Guia, uc.Guia); UpdateOrCreateLine(SimGeometria, uc.Guia);
} }
public osGuia() public osGuia()
@ -133,13 +100,13 @@ namespace CtrEditor.ObjetosSim
ActualizarLeftTop(); ActualizarLeftTop();
if (_visualRepresentation is ucGuia uc) if (_visualRepresentation is ucGuia uc)
Simulation_Guia = AddLine(simulationManager, uc.Guia); SimGeometria = AddLine(simulationManager, uc.Guia);
} }
public override void ucUnLoaded() public override void ucUnLoaded()
{ {
// El UserControl se esta eliminando // El UserControl se esta eliminando
// eliminar el objeto de simulacion // eliminar el objeto de simulacion
simulationManager.Remove(Simulation_Guia); simulationManager?.Remove(SimGeometria);
} }

View File

@ -5,13 +5,19 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:localuc="clr-namespace:CtrEditor.ObjetosSim.UserControls" xmlns:localuc="clr-namespace:CtrEditor.ObjetosSim.UserControls"
xmlns:convert="clr-namespace:CtrEditor.Convertidores" xmlns:convert="clr-namespace:CtrEditor.Convertidores"
xmlns:vm="clr-namespace:CtrEditor.ObjetosSim"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources> <UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/> <convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources> </UserControl.Resources>
<Canvas>
<localuc:CircularSegment x:Name="Transporte" Angle="{Binding Angulo}" OuterRadius="{Binding RadioExterno, Converter={StaticResource MeterToPixelConverter}}" InnerRadius="{Binding RadioInterno, Converter={StaticResource MeterToPixelConverter}}" <UserControl.DataContext>
StartAngle="0" EndAngle="90" /> <vm:osTransporteCurva />
</UserControl.DataContext>
<Canvas x:Name="MainCanvas">
<localuc:CircularSegment x:Name="Transporte" Angle="0" OuterRadius="{Binding RadioExterno, Converter={StaticResource MeterToPixelConverter}}" InnerRadius="{Binding RadioInterno, Converter={StaticResource MeterToPixelConverter}}"
StartAngle="{Binding Angulo}" EndAngle="{Binding AnguloFinal}" />
</Canvas> </Canvas>
</UserControl> </UserControl>

View File

@ -23,32 +23,18 @@ namespace CtrEditor.ObjetosSim
private osBase _osMotor = null; private osBase _osMotor = null;
private string _motor; private string _motor;
private simTransporte Simulation_Transporte; private simCurve Simulation_TransporteCurva;
public static string NombreClase() public static string NombreClase()
{ {
return "Transporte Curva 90"; return "Transporte Curva 90";
} }
private string nombre = "Transporte Curva 90";
private float angulo; public override string Nombre
public float Angulo
{ {
get => angulo; get => nombre;
set set => SetProperty(ref nombre, value);
{
ActualizarGeometrias();
SetProperty(ref angulo, value);
} }
}
[ObservableProperty]
private float radioExterno;
[ObservableProperty]
private float radioInterno;
[ObservableProperty]
private string motor;
private float left; private float left;
public override float Left public override float Left
@ -72,11 +58,25 @@ namespace CtrEditor.ObjetosSim
} }
[ObservableProperty] [ObservableProperty]
public float ancho; private float radioExterno;
[ObservableProperty]
private float radioInterno;
[ObservableProperty]
private string motor;
[ObservableProperty] [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 public float VelocidadActual
{ {
@ -84,24 +84,17 @@ namespace CtrEditor.ObjetosSim
set set
{ {
_velocidadActual = value; _velocidadActual = value;
Simulation_Transporte?.SetSpeed(value); Simulation_TransporteCurva?.SetSpeed(value);
OnPropertyChanged(nameof(VelocidadActual)); OnPropertyChanged(nameof(VelocidadActual));
} }
} }
private string nombre = "Transporte Curva 90";
public override string Nombre
{
get => nombre;
set => SetProperty(ref nombre, value);
}
private void ActualizarGeometrias() private void ActualizarGeometrias()
{ {
if (_visualRepresentation is ucTransporteCurva uc) if (_visualRepresentation is ucTransporteCurva uc)
{ {
//UpdateRectangle(Simulation_Transporte, uc.Transporte, Alto, Ancho, Angulo); UpdateCurve(Simulation_TransporteCurva, RadioInterno, RadioExterno, Angulo, Angulo+Arco_en_grados);
Simulation_Transporte.Speed = VelocidadActual; Simulation_TransporteCurva.Speed = VelocidadActual;
} }
} }
@ -112,10 +105,9 @@ namespace CtrEditor.ObjetosSim
public osTransporteCurva() public osTransporteCurva()
{ {
Ancho = 1; RadioExterno = 1.3f;
Alto = 0.10f;
RadioExterno = 2;
RadioInterno = 1; RadioInterno = 1;
Arco_en_grados = 90;
} }
public override void UpdateGeometryStart() public override void UpdateGeometryStart()
@ -146,14 +138,16 @@ namespace CtrEditor.ObjetosSim
// crear el objeto de simulacion // crear el objeto de simulacion
ActualizarLeftTop(); ActualizarLeftTop();
//if (_visualRepresentation is ucTransporteCurva uc) if (_visualRepresentation is ucTransporteCurva uc)
// Simulation_Transporte = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo); 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() public override void ucUnLoaded()
{ {
// El UserControl se esta eliminando // El UserControl se esta eliminando
// eliminar el objeto de simulacion // eliminar el objeto de simulacion
simulationManager.Remove(Simulation_Transporte); simulationManager?.Remove(Simulation_TransporteCurva);
} }
} }
@ -176,10 +170,16 @@ namespace CtrEditor.ObjetosSim
{ {
Datos?.ucUnLoaded(); Datos?.ucUnLoaded();
} }
public void Resize(float width, float height) public void Resize(float RadioExterno, float RadioInterno)
{ {
if (Datos is osTransporteCurva datos) 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) public void Move(float LeftPixels, float TopPixels)
{ {

View File

@ -4,19 +4,62 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" 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">
<UserControl.Resources> <UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/> <convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
<convert:SpeedAndWidthToDurationConverter x:Key="SpeedAndWidthToDurationConverter"/>
<!-- Define the VisualBrush for the conveyor belt pattern -->
<VisualBrush x:Key="BeltBrush" TileMode="Tile" Viewport="0,0,0.1,1" ViewportUnits="RelativeToBoundingBox" Viewbox="0,0,20,10" ViewboxUnits="Absolute">
<VisualBrush.Transform>
<TranslateTransform x:Name="BrushTransform"/>
</VisualBrush.Transform>
<VisualBrush.Visual>
<Canvas>
<Rectangle Fill="Gray" Width="10" Height="10"/>
<Rectangle Fill="DarkGray" Width="10" Height="10" Canvas.Left="10"/>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</UserControl.Resources> </UserControl.Resources>
<UserControl.DataContext>
<vm:osTransporteTTop Ancho="2"/>
</UserControl.DataContext>
<Canvas> <Canvas>
<Rectangle x:Name="Transporte" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Fill="Gray"> <Rectangle x:Name="Transporte"
Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}"
Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}"
Fill="{StaticResource BeltBrush}">
<Rectangle.RenderTransform> <Rectangle.RenderTransform>
<RotateTransform Angle="{Binding Angulo}"/> <RotateTransform Angle="{Binding Angulo}"/>
</Rectangle.RenderTransform> </Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.Fill).(VisualBrush.Transform).(TranslateTransform.X)"
From="0" To="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}">
<DoubleAnimation.Duration>
<MultiBinding Converter="{StaticResource SpeedAndWidthToDurationConverter}">
<Binding Path="VelocidadActual"/>
<Binding Path="Ancho"/>
</MultiBinding>
</DoubleAnimation.Duration>
<DoubleAnimation.RepeatBehavior>Forever</DoubleAnimation.RepeatBehavior>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle> </Rectangle>
</Canvas> </Canvas>
</UserControl> </UserControl>

View File

@ -1,5 +1,8 @@
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media.Animation;
using System.Windows.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CtrEditor.Convertidores; using CtrEditor.Convertidores;
using CtrEditor.Siemens; using CtrEditor.Siemens;
using CtrEditor.Simulacion; using CtrEditor.Simulacion;
@ -12,23 +15,9 @@ namespace CtrEditor.ObjetosSim
/// </summary> /// </summary>
/// ///
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 osBase _osMotor = null;
private string _motor;
private simTransporte Simulation_Transporte; private simTransporte Simulation_Transporte;
@ -36,90 +25,62 @@ namespace CtrEditor.ObjetosSim
{ {
return "Transporte"; return "Transporte";
} }
public string Motor private string nombre = "Transporte TTOP";
{
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));
}
}
public override string Nombre public override string Nombre
{ {
get => _nombre; get => nombre;
set => SetProperty(ref nombre, value);
}
private float left;
public override float Left
{
get => left;
set set
{ {
if (_nombre != value) CanvasSetLeftinMeter(value);
SetProperty(ref left, value);
}
}
private float top;
public override float Top
{ {
_nombre = value; get => top;
OnPropertyChanged(nameof(Nombre)); 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() 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() public osTransporteTTop()
{ {
@ -157,7 +114,7 @@ namespace CtrEditor.ObjetosSim
VelocidadActual = motor.Velocidad; VelocidadActual = motor.Velocidad;
} }
else else
_osMotor = ObtenerLink(_motor, typeof(osVMmotorSim)); _osMotor = ObtenerLink(Motor, typeof(osVMmotorSim));
} }
public override void UpdateControl(int elapsedMilliseconds) public override void UpdateControl(int elapsedMilliseconds)

View File

@ -250,6 +250,18 @@ namespace CtrEditor.ObjetosSim
return (start, end); 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) 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); 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) public void UpdateRectangle(simTransporte simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
{ {
if (simRect != null) if (simRect != null)
@ -274,6 +288,16 @@ namespace CtrEditor.ObjetosSim
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); 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) public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
{ {
return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);

View File

@ -14,6 +14,7 @@ using System.Windows;
using System.Diagnostics; using System.Diagnostics;
using FarseerPhysics.Dynamics.Joints; using FarseerPhysics.Dynamics.Joints;
using CtrEditor.ObjetosSim;
namespace CtrEditor.Simulacion namespace CtrEditor.Simulacion
{ {
@ -42,6 +43,7 @@ namespace CtrEditor.Simulacion
private float _outerRadius; private float _outerRadius;
private float _startAngle; private float _startAngle;
private float _endAngle; 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) public simCurve(World world, float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
{ {
@ -53,13 +55,20 @@ namespace CtrEditor.Simulacion
Create(position); Create(position);
} }
private void Create(Vector2 position) public void Create(float innerRadius, float outerRadius, float startAngle, float endAngle, Vector2 position)
{ {
if (Body != null) if (_world == null) return;
{ _innerRadius = innerRadius;
_world.RemoveBody(Body); _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 // Crear la geometría del sensor de curva
List<Vertices> segments = CreateCurveVertices(_innerRadius, _outerRadius, _startAngle, _endAngle); List<Vertices> segments = CreateCurveVertices(_innerRadius, _outerRadius, _startAngle, _endAngle);
Body = new Body(_world); Body = new Body(_world);
@ -74,6 +83,11 @@ namespace CtrEditor.Simulacion
Body.UserData = this; Body.UserData = this;
} }
public void SetSpeed(float speed)
{
Speed = speed;
}
private List<Vertices> CreateCurveVertices(float innerRadius, float outerRadius, float startAngle, float endAngle) private List<Vertices> CreateCurveVertices(float innerRadius, float outerRadius, float startAngle, float endAngle)
{ {
List<Vertices> verticesList = new List<Vertices>(); List<Vertices> verticesList = new List<Vertices>();
@ -97,24 +111,24 @@ namespace CtrEditor.Simulacion
return verticesList; return verticesList;
} }
public void ApplyCurveEffect(simBotella bottle) public void ApplyCurveEffect(Fixture bottle)
{ {
// Crear un joint para mantener la botella en la curva Vector2 centerToBottle = bottle.Body.Position - Body.Position;
RevoluteJoint joint = new RevoluteJoint(bottle.Body, Body, Body.Position, true) float distanceToCenter = centerToBottle.Length();
{
CollideConnected = false
};
_world.AddJoint(joint);
bottle.CurrentJoint = joint; if (distanceToCenter >= _innerRadius && distanceToCenter <= _outerRadius)
} {
// Calcular la velocidad tangencial
float speedMetersPerSecond = Speed / 60.0f;
float angularVelocity = speedMetersPerSecond / distanceToCenter;
public void RemoveCurveEffect(simBotella bottle) // Vector tangente (perpendicular al radio)
{ Vector2 tangent = new Vector2(-centerToBottle.Y, centerToBottle.X);
if (bottle.CurrentJoint != null) tangent.Normalize();
{
_world.RemoveJoint(bottle.CurrentJoint); // Velocidad deseada
bottle.CurrentJoint = null; Vector2 desiredVelocity = tangent * angularVelocity * distanceToCenter;
bottle.Body.LinearVelocity = desiredVelocity;
} }
} }
} }
@ -261,7 +275,6 @@ namespace CtrEditor.Simulacion
private float _radius; private float _radius;
private float _mass; private float _mass;
public bool Descartar = false; public bool Descartar = false;
public RevoluteJoint CurrentJoint { get; set; }
public simBotella(World world, float diameter, Vector2 position, float mass) 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) else if (fixtureB.Body.UserData is simCurve curve)
{ {
curve.ApplyCurveEffect(this); curve.ApplyCurveEffect(fixtureA);
return true; // No aplicar respuestas físicas return true; // No aplicar respuestas físicas
} }
else if (fixtureB.Body.UserData is simDescarte) else if (fixtureB.Body.UserData is simDescarte)
@ -351,6 +364,9 @@ namespace CtrEditor.Simulacion
} else if (fixtureB.Body.UserData is simTransporte) } else if (fixtureB.Body.UserData is simTransporte)
{ {
simTransporte conveyor = fixtureB.Body.UserData as simTransporte; simTransporte conveyor = fixtureB.Body.UserData as simTransporte;
if ( conveyor.Speed != 0 ) {
CircleShape circleShape = fixtureA.Shape as CircleShape; CircleShape circleShape = fixtureA.Shape as CircleShape;
PolygonShape polygonShape = fixtureB.Shape as PolygonShape; PolygonShape polygonShape = fixtureB.Shape as PolygonShape;
@ -376,15 +392,10 @@ namespace CtrEditor.Simulacion
// Aplicar el efecto del transportador usando el porcentaje calculado // Aplicar el efecto del transportador usando el porcentaje calculado
ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido); ApplyConveyorEffect(conveyor, fixtureA, porcentajeCompartido);
return true; // No aplicar respuestas físicas
} }
return true; // No aplicar respuestas físicas 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) private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido)
@ -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) public simBotella AddCircle(float diameter, Vector2 position, float mass)
{ {
simBotella circle = new simBotella(world, diameter, position, mass); simBotella circle = new simBotella(world, diameter, position, mass);