diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 1c12902..8ec5b76 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -106,7 +106,11 @@ namespace CtrEditor.ObjetosSim LeftChanging(oldValue, newValue); } - public virtual void LeftChanged(float value) { } + public virtual void LeftChanged(float value) + { + // Actualizar posición relativa si el movimiento no viene del FramePlate + UpdateFramePlateRelativePosition(); + } public virtual void LeftChanging(float oldValue, float newValue) { } [ObservableProperty] @@ -124,7 +128,11 @@ namespace CtrEditor.ObjetosSim TopChanging(oldValue, newValue); } - public virtual void TopChanged(float value) { } + public virtual void TopChanged(float value) + { + // Actualizar posición relativa si el movimiento no viene del FramePlate + UpdateFramePlateRelativePosition(); + } public virtual void TopChanging(float oldValue, float newValue) { } @@ -289,6 +297,22 @@ namespace CtrEditor.ObjetosSim [JsonIgnore] private bool isUpdatingFromFramePlate = false; + // Variables para rotación orbital alrededor del FramePlate + [JsonIgnore] + [ObservableProperty] + [property: Hidden] + private float framePlate_RelativeX; + + [JsonIgnore] + [ObservableProperty] + [property: Hidden] + private float framePlate_RelativeY; + + [JsonIgnore] + [ObservableProperty] + [property: Hidden] + private float framePlate_InitialAngle; + partial void OnGroup_FramePanelChanged(string value) { if (FramePlate != null) @@ -300,8 +324,20 @@ namespace CtrEditor.ObjetosSim { FramePlate.PropertyChanged += OnFramePlatePropertyChanged; UpdateZIndex(FramePlate.Zindex_FramePlate); + + // Calcular posición relativa inicial respecto al FramePlate + FramePlate_RelativeX = Left - FramePlate.Left; + FramePlate_RelativeY = Top - FramePlate.Top; + FramePlate_InitialAngle = FramePlate.Angulo; } } + else + { + // Reset relative position when disconnecting + FramePlate_RelativeX = 0; + FramePlate_RelativeY = 0; + FramePlate_InitialAngle = 0; + } } protected void UpdateZIndex(int zIndex) @@ -322,22 +358,16 @@ namespace CtrEditor.ObjetosSim if (e.PropertyName == nameof(osFramePlate.Nombre)) Group_Panel = ((osFramePlate)sender).Nombre; - if (e.PropertyName == nameof(osFramePlate.Top)) + if (e.PropertyName == nameof(osFramePlate.Top) || + e.PropertyName == nameof(osFramePlate.Left)) { - Top += ((osFramePlate)sender).offsetY; - OnMoveResizeRotate(); - } - - if (e.PropertyName == nameof(osFramePlate.Left)) - { - Left += ((osFramePlate)sender).offsetX; - OnMoveResizeRotate(); + UpdateOrbitalPosition(); } if (e.PropertyName == nameof(osFramePlate.Angulo)) { + UpdateOrbitalPosition(); Angulo += ((osFramePlate)sender).offsetAngulo; - OnMoveResizeRotate(); } if (e.PropertyName == nameof(osFramePlate.Zindex_FramePlate)) @@ -347,6 +377,54 @@ namespace CtrEditor.ObjetosSim } } + private void UpdateOrbitalPosition() + { + if (FramePlate == null) return; + + // Calcular el ángulo de rotación total desde la posición inicial + float deltaAngle = FramePlate.Angulo - FramePlate_InitialAngle; + + // Convertir ángulo a radianes + float angleRad = deltaAngle * (float)Math.PI / 180.0f; + + // Calcular la nueva posición orbital usando rotación de matriz + float cosAngle = (float)Math.Cos(angleRad); + float sinAngle = (float)Math.Sin(angleRad); + + // Rotar la posición relativa + float rotatedX = cosAngle * FramePlate_RelativeX - sinAngle * FramePlate_RelativeY; + float rotatedY = sinAngle * FramePlate_RelativeX + cosAngle * FramePlate_RelativeY; + + // Calcular nueva posición absoluta + Left = FramePlate.Left + rotatedX; + Top = FramePlate.Top + rotatedY; + + OnMoveResizeRotate(); + } + + private void UpdateFramePlateRelativePosition() + { + // Solo actualizar si está conectado a un FramePlate y el movimiento NO viene del FramePlate + if (FramePlate != null && !isUpdatingFromFramePlate) + { + // Recalcular posición relativa considerando la rotación actual del FramePlate + float deltaAngle = FramePlate.Angulo - FramePlate_InitialAngle; + float angleRad = deltaAngle * (float)Math.PI / 180.0f; + + // Calcular la posición relativa actual respecto al FramePlate + float currentRelativeX = Left - FramePlate.Left; + float currentRelativeY = Top - FramePlate.Top; + + // Si el FramePlate está rotado, necesitamos "desrotar" la posición para obtener + // la posición relativa en el sistema de coordenadas original + float cosAngle = (float)Math.Cos(-angleRad); + float sinAngle = (float)Math.Sin(-angleRad); + + FramePlate_RelativeX = cosAngle * currentRelativeX - sinAngle * currentRelativeY; + FramePlate_RelativeY = sinAngle * currentRelativeX + cosAngle * currentRelativeY; + } + } + private void ShowPreviewWindow(Stream imageStream) {