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
{
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)

View File

@ -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<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...

View File

@ -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<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);
}
if (DataContext is MainViewModel viewModel)
viewModel.CargarPropiedadesosDatos(selectedObject, PanelEdicion, Resources);
}
private void MainWindow_Closed(object sender, EventArgs e)
{
if (DataContext is MainViewModel viewModel)

View File

@ -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">
<UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources>
<UserControl.DataContext>
<vm:osGuia/>
</UserControl.DataContext>
<Canvas>
<Rectangle x:Name="Guia" Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding AltoGuia, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue">
<Rectangle.RenderTransform>

View File

@ -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
/// <summary>
/// Interaction logic for ucGuia.xaml
/// </summary>
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);
}

View File

@ -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">
<UserControl.Resources>
<convert:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
</UserControl.Resources>
<Canvas>
<localuc:CircularSegment x:Name="Transporte" Angle="{Binding Angulo}" OuterRadius="{Binding RadioExterno, Converter={StaticResource MeterToPixelConverter}}" InnerRadius="{Binding RadioInterno, Converter={StaticResource MeterToPixelConverter}}"
StartAngle="0" EndAngle="90" />
<UserControl.DataContext>
<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>
</UserControl>

View File

@ -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)
{

View File

@ -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">
<UserControl.Resources>
<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.DataContext>
<vm:osTransporteTTop Ancho="2"/>
</UserControl.DataContext>
<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>
<RotateTransform Angle="{Binding Angulo}"/>
</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>
</Canvas>
</UserControl>

View File

@ -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
/// </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 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)

View File

@ -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);

View File

@ -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<Vertices> 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<Vertices> CreateCurveVertices(float innerRadius, float outerRadius, float startAngle, float endAngle)
{
List<Vertices> verticesList = new List<Vertices>();
@ -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);