diff --git a/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml b/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml
new file mode 100644
index 0000000..a312b35
--- /dev/null
+++ b/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
diff --git a/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml.cs b/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml.cs
new file mode 100644
index 0000000..3b118c7
--- /dev/null
+++ b/ObjetosSim/Estaticos/ucTransporteCurvaGuias.xaml.cs
@@ -0,0 +1,283 @@
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Controls;
+using CommunityToolkit.Mvvm.ComponentModel;
+using LibS7Adv;
+using CtrEditor.Simulacion;
+using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
+using CtrEditor.FuncionesBase;
+using System.Text.Json.Serialization;
+
+namespace CtrEditor.ObjetosSim
+{
+ ///
+ /// Interaction logic for ucTransporteCurvaGuias.xaml
+ ///
+ public partial class osTransporteCurvaGuias : osBase, IosBase
+ {
+ private osBase Motor = null;
+
+ private simCurve Simulation_TransporteCurvaGuias;
+
+ private float _velocidadActual;
+
+ public static string NombreClase()
+ {
+ return "Transporte Curva 90";
+ }
+ private string nombre = "Transporte Curva 90";
+ public override string Nombre
+ {
+ get => nombre;
+ set => SetProperty(ref nombre, value);
+ }
+
+ [ObservableProperty]
+ public float velocidadActual;
+
+ partial void OnVelocidadActualChanged(float value)
+ {
+ SetSpeed();
+ }
+
+ [ObservableProperty]
+ bool invertirDireccion;
+
+ partial void OnInvertirDireccionChanged(bool value)
+ {
+ SetSpeed();
+ if (_visualRepresentation is ucTransporteCurvaGuias uc)
+ {
+ CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
+ ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
+ }
+ }
+
+ void SetSpeed()
+ {
+ if (InvertirDireccion)
+ Simulation_TransporteCurvaGuias?.SetSpeed(-VelocidadActual);
+ else
+ Simulation_TransporteCurvaGuias?.SetSpeed(VelocidadActual);
+ ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
+ }
+
+ [ObservableProperty]
+ private float radioExterno;
+
+ partial void OnRadioExternoChanged(float value)
+ {
+ // Update ancho and alto based on radioExterno
+ Ancho = value * 2;
+ Alto = value * 2;
+
+ // Ensure radioInterno maintains proper proportion if needed
+ if (RadioInterno >= value)
+ {
+ RadioInterno = value * 0.75f; // Default proportion
+ }
+
+ ActualizarGeometrias();
+ }
+
+ [ObservableProperty]
+ private float radioInterno;
+
+
+
+ [ObservableProperty]
+ [property: Description("Bit to enable Link to Motor")]
+ [property: Category("PLC link:")]
+ string tag_ReleActivatedMotor;
+
+ [ObservableProperty]
+ [property: Description("Link to Motor")]
+ [property: Category("PLC link:")]
+ [property: ItemsSource(typeof(osBaseItemsSource))]
+ string id_Motor;
+
+ [JsonIgnore]
+ private PropertyChangedEventHandler motorPropertyChangedHandler;
+
+ partial void OnId_MotorChanged(string value)
+ {
+ if (Motor != null && motorPropertyChangedHandler != null)
+ Motor.PropertyChanged -= motorPropertyChangedHandler;
+
+ if (_mainViewModel != null && !string.IsNullOrEmpty(value))
+ {
+ Motor = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => s is osVMmotorSim motor && motor.Nombre == value);
+ if (Motor != null)
+ {
+ motorPropertyChangedHandler = (sender, e) =>
+ {
+ if (e.PropertyName == nameof(osVMmotorSim.Nombre))
+ {
+ Id_Motor = ((osVMmotorSim)sender).Nombre;
+ }
+ };
+ Motor.PropertyChanged += motorPropertyChangedHandler;
+ }
+ }
+ }
+
+ public override void AnguloChanged(float value)
+ {
+ OnPropertyChanged(nameof(AnguloFinal));
+ }
+
+ [ObservableProperty]
+ [NotifyPropertyChangedFor(nameof(AnguloFinal))]
+ private float arco_en_grados;
+
+ [Hidden]
+ public float AnguloFinal
+ {
+ get => Angulo + Arco_en_grados;
+ }
+
+ private void ActualizarGeometrias()
+ {
+ if (_visualRepresentation is ucTransporteCurvaGuias uc)
+ {
+ UpdateCurve(Simulation_TransporteCurvaGuias, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
+ SetSpeed();
+ }
+ }
+
+ public override void OnMoveResizeRotate()
+ {
+ ActualizarGeometrias();
+ }
+
+ [ObservableProperty]
+ public float frictionCoefficient;
+ [ObservableProperty]
+ public float velMax50hz;
+ [ObservableProperty]
+ public float tiempoRampa;
+ [ObservableProperty]
+ public bool esMarcha;
+
+ public override void OnResize(float Delta_Width, float Delta_Height)
+ {
+ // Calculate the proportional change factor
+ float widthChangeFactor = (Ancho + Delta_Width) / Ancho;
+ float heightChangeFactor = (Alto + Delta_Height) / Alto;
+
+ // Use the average or minimum change factor to maintain aspect ratio
+ float changeFactor = Math.Min(widthChangeFactor, heightChangeFactor);
+
+ // Save the original radiuses for calculating position adjustments
+ float originalRadioExterno = RadioExterno;
+
+ // Apply the change factor to both radios
+ RadioExterno *= changeFactor;
+ RadioInterno *= changeFactor;
+
+ // Calculate position adjustment to keep the component centered
+ float radiusDifference = RadioExterno - originalRadioExterno;
+
+ // Adjust Left and Top to maintain center position
+ // We move by negative half the difference because the component expands outward
+ Left -= radiusDifference;
+ Top -= radiusDifference;
+
+ // Ensure minimums
+ if (RadioExterno < 0.1f)
+ RadioExterno = 0.1f;
+
+ if (RadioInterno < 0.05f)
+ RadioInterno = 0.05f;
+
+ // Ensure radioInterno is always less than radioExterno
+ if (RadioInterno >= RadioExterno)
+ RadioInterno = RadioExterno * 0.75f;
+ }
+
+
+
+ public osTransporteCurvaGuias()
+ {
+ RadioExterno = 1.3f;
+ RadioInterno = 1f;
+ Ancho = RadioExterno * 2; // Set initial width based on external radius
+ Alto = RadioExterno * 2; // Set initial height based on external radius
+ Arco_en_grados = 90;
+ Tag_ReleActivatedMotor = "1";
+ }
+
+ public override void UpdateGeometryStart()
+ {
+ // Se llama antes de la simulacion
+ ActualizarGeometrias();
+ }
+
+ public override void SimulationStop()
+ {
+ // Se llama al detener la simulacion
+ ActualizarAnimacionStoryBoardTransporte(VelocidadActual);
+ }
+
+ public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
+ {
+ if (Motor != null)
+ {
+ if (Motor is osVMmotorSim motor)
+ if (LeerBitTag(Tag_ReleActivatedMotor))
+ VelocidadActual = motor.Velocidad;
+ else
+ VelocidadActual = 0;
+ }
+ }
+
+ public override void ucLoaded()
+ {
+ // El UserControl ya se ha cargado y podemos obtener las coordenadas para
+ // crear el objeto de simulacion
+ base.ucLoaded();
+ OnId_MotorChanged(Id_Motor); // Link Id_Motor = Motor
+
+ if (_visualRepresentation is ucTransporteCurvaGuias uc)
+ {
+ Simulation_TransporteCurvaGuias = AddCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
+ CrearAnimacionStoryBoardTrasnporteCircular(uc.Transporte.TransportePath, InvertirDireccion, Angulo);
+ }
+ }
+ public override void ucUnLoaded()
+ {
+ // El UserControl se esta eliminando
+ // eliminar el objeto de simulacion
+ simulationManager?.Remove(Simulation_TransporteCurvaGuias);
+ }
+
+ }
+
+ public partial class ucTransporteCurvaGuias : UserControl, IDataContainer
+ {
+ public osBase? Datos { get; set; }
+ public int zIndex_fromFrames { get; set; }
+
+ public ucTransporteCurvaGuias()
+ {
+ InitializeComponent();
+ this.Loaded += OnLoaded;
+ this.Unloaded += OnUnloaded;
+ }
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ Datos?.ucLoaded();
+ }
+ private void OnUnloaded(object sender, RoutedEventArgs e)
+ {
+ Datos?.ucUnLoaded();
+ }
+ public void Highlight(bool State) { }
+ public ZIndexEnum ZIndex_Base()
+ {
+ return ZIndexEnum.Estaticos;
+ }
+
+ }
+
+}