Se implementaron mejoras en la gestión de copias de objetos seleccionados, reutilizando la lógica de duplicación para crear copias serializables. Se agregó manejo de errores al intentar copiar objetos y se implementaron nuevas propiedades en la clase osBase para gestionar el punto de pivote en la rotación. Además, se aseguraron validaciones para evitar diámetros inválidos en la simulación, garantizando un comportamiento más robusto en la manipulación de objetos.
This commit is contained in:
parent
f85c707cfc
commit
99248e9112
|
@ -16,7 +16,6 @@ using System.Text.RegularExpressions;
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CtrEditor
|
||||
{
|
||||
|
@ -817,38 +816,46 @@ namespace CtrEditor
|
|||
|
||||
try
|
||||
{
|
||||
var objectsToCopy = new List<osBase>();
|
||||
|
||||
// Preparar objetos para serialización
|
||||
foreach (var obj in _objectManager.SelectedObjects)
|
||||
if (DataContext is MainViewModel viewModel)
|
||||
{
|
||||
obj.SalvarDatosNoSerializables();
|
||||
objectsToCopy.Add(obj);
|
||||
}
|
||||
// Usar la misma lógica que DuplicarObjeto pero solo para crear copias para serialización
|
||||
var objectsCopy = new List<osBase>();
|
||||
|
||||
foreach (var originalObj in _objectManager.SelectedObjects)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Reutilizar la lógica existente de DuplicarObjeto sin añadir a ObjetosSimulables
|
||||
var tempCopy = CreateCopyUsingExistingLogic(viewModel, originalObj);
|
||||
if (tempCopy != null)
|
||||
{
|
||||
objectsCopy.Add(tempCopy);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error al crear copia de {originalObj.Nombre}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Crear configuración de serialización igual a la usada en el guardado
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
||||
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
|
||||
};
|
||||
if (objectsCopy.Count == 0)
|
||||
{
|
||||
MessageBox.Show("No se pudieron copiar los objetos seleccionados.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Serializar objetos
|
||||
string jsonString = JsonConvert.SerializeObject(objectsToCopy, settings);
|
||||
// Serializar usando las mismas configuraciones que DuplicarObjeto
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
TypeNameHandling = TypeNameHandling.All // Igual que en DuplicarObjeto
|
||||
};
|
||||
|
||||
// Copiar al portapapeles
|
||||
Clipboard.SetText(jsonString);
|
||||
|
||||
// Mostrar mensaje de confirmación
|
||||
Console.WriteLine($"Copiados {objectsToCopy.Count} objeto(s) al portapapeles");
|
||||
|
||||
// Restaurar datos no serializables
|
||||
foreach (var obj in _objectManager.SelectedObjects)
|
||||
{
|
||||
obj.RestaurarDatosNoSerializables();
|
||||
string jsonString = JsonConvert.SerializeObject(objectsCopy, settings);
|
||||
Clipboard.SetText(jsonString);
|
||||
|
||||
Console.WriteLine($"Copiados {objectsCopy.Count} objeto(s) al portapapeles");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -857,6 +864,33 @@ namespace CtrEditor
|
|||
}
|
||||
}
|
||||
|
||||
private osBase CreateCopyUsingExistingLogic(MainViewModel viewModel, osBase original)
|
||||
{
|
||||
// Usar exactamente la misma lógica que DuplicarObjeto pero sin añadir a la colección
|
||||
osBase copy = null;
|
||||
|
||||
original.SalvarDatosNoSerializables();
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
TypeNameHandling = TypeNameHandling.All // Igual que en DuplicarObjeto
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var serializedData = JsonConvert.SerializeObject(original, settings);
|
||||
copy = JsonConvert.DeserializeObject<osBase>(serializedData, settings);
|
||||
}
|
||||
finally
|
||||
{
|
||||
original.RestaurarDatosNoSerializables();
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
private void PasteObjectsFromJson(bool replaceExistingIds = false)
|
||||
{
|
||||
if (!Clipboard.ContainsText())
|
||||
|
@ -945,27 +979,21 @@ namespace CtrEditor
|
|||
obj.Left += offsetX;
|
||||
obj.Top += offsetY;
|
||||
|
||||
// Manejar IDs
|
||||
// Manejar IDs usando la misma lógica que DuplicarObjeto
|
||||
if (!replaceExistingIds)
|
||||
{
|
||||
// Generar nuevo ID (comportamiento por defecto)
|
||||
// Generar nuevo ID y actualizar nombre (igual que en DuplicarObjeto)
|
||||
obj.Id.ObtenerNuevaID();
|
||||
|
||||
// Actualizar nombre si contiene ID
|
||||
if (obj.Nombre.Contains("_"))
|
||||
{
|
||||
var parts = obj.Nombre.Split('_');
|
||||
if (parts.Length > 1 && int.TryParse(parts.Last(), out _))
|
||||
{
|
||||
obj.Nombre = string.Join("_", parts.Take(parts.Length - 1)) + "_" + obj.Id.Value;
|
||||
}
|
||||
}
|
||||
string nombre = Regex.IsMatch(obj.Nombre, @"_\d+$")
|
||||
? Regex.Replace(obj.Nombre, @"_\d+$", $"_{obj.Id.Value}")
|
||||
: obj.Nombre + "_" + obj.Id.Value;
|
||||
|
||||
obj.Nombre = nombre;
|
||||
}
|
||||
// Si replaceExistingIds es true, mantener los IDs originales
|
||||
|
||||
// Verificar que el objeto no existe ya si estamos reemplazando IDs
|
||||
if (replaceExistingIds)
|
||||
else
|
||||
{
|
||||
// Reemplazar objeto existente con mismo ID
|
||||
var existingObj = viewModel.ObjetosSimulables.FirstOrDefault(o => o.Id.Value == obj.Id.Value);
|
||||
if (existingObj != null)
|
||||
{
|
||||
|
@ -976,6 +1004,7 @@ namespace CtrEditor
|
|||
obj.CheckData();
|
||||
viewModel.ObjetosSimulables.Add(obj);
|
||||
viewModel.CrearUserControlDesdeObjetoSimulable(obj);
|
||||
viewModel.HasUnsavedChanges = true;
|
||||
|
||||
newlyPastedObjects.Add(obj);
|
||||
}
|
||||
|
@ -985,78 +1014,49 @@ namespace CtrEditor
|
|||
}
|
||||
}
|
||||
|
||||
// Forzar actualización del layout para asegurar que los objetos estén renderizados
|
||||
// Usar la misma lógica de selección que DuplicarUserControl
|
||||
// Limpiar selección antes de seleccionar los nuevos objetos
|
||||
_objectManager.ClearSelection();
|
||||
|
||||
// Forzar actualización completa del layout
|
||||
ImagenEnTrabajoCanvas.UpdateLayout();
|
||||
|
||||
// Usar Task.Delay para dar más tiempo al renderizado completo
|
||||
Task.Delay(100).ContinueWith(_ =>
|
||||
// Usar dispatcher con la misma prioridad que DuplicarUserControl
|
||||
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() =>
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
// Seleccionar todos los objetos pegados
|
||||
foreach (var newObj in newlyPastedObjects)
|
||||
{
|
||||
try
|
||||
if (newObj.VisualRepresentation != null)
|
||||
{
|
||||
// Forzar una segunda actualización del layout
|
||||
ImagenEnTrabajoCanvas.UpdateLayout();
|
||||
double left = Canvas.GetLeft(newObj.VisualRepresentation);
|
||||
double top = Canvas.GetTop(newObj.VisualRepresentation);
|
||||
|
||||
// Validar que los objetos tengan representación visual antes de seleccionar
|
||||
var validObjects = newlyPastedObjects.Where(obj =>
|
||||
obj.VisualRepresentation != null &&
|
||||
ImagenEnTrabajoCanvas.Children.Contains(obj.VisualRepresentation)).ToList();
|
||||
|
||||
Console.WriteLine($"Intentando seleccionar {validObjects.Count} de {newlyPastedObjects.Count} objetos pegados");
|
||||
|
||||
if (validObjects.Count > 0)
|
||||
// Solo añadir a selección si el objeto tiene coordenadas válidas
|
||||
if (!double.IsNaN(left) && !double.IsNaN(top) && !double.IsInfinity(left) && !double.IsInfinity(top))
|
||||
{
|
||||
// Limpiar selección actual primero
|
||||
_objectManager.ClearSelection();
|
||||
|
||||
// Seleccionar los objetos válidos uno por uno con verificación
|
||||
foreach (var obj in validObjects)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (obj.VisualRepresentation != null)
|
||||
{
|
||||
Console.WriteLine($"Seleccionando objeto: {obj.Nombre} (ID: {obj.Id.Value})");
|
||||
_objectManager.SelectObject(obj);
|
||||
}
|
||||
}
|
||||
catch (Exception objEx)
|
||||
{
|
||||
Console.WriteLine($"Error al seleccionar objeto {obj.Nombre}: {objEx.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Actualizar visuales de selección con manejo de errores
|
||||
try
|
||||
{
|
||||
_objectManager.UpdateSelectionVisuals();
|
||||
Console.WriteLine($"Seleccionados exitosamente {_objectManager.SelectedObjects.Count} objetos");
|
||||
}
|
||||
catch (Exception visEx)
|
||||
{
|
||||
Console.WriteLine($"Error al actualizar visuales de selección: {visEx.Message}");
|
||||
Console.WriteLine($"Stack trace: {visEx.StackTrace}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("No se pudieron seleccionar los objetos pegados - representación visual no válida");
|
||||
foreach (var obj in newlyPastedObjects)
|
||||
{
|
||||
Console.WriteLine($"Objeto {obj.Nombre}: VisualRep={obj.VisualRepresentation != null}, EnCanvas={obj.VisualRepresentation != null && ImagenEnTrabajoCanvas.Children.Contains(obj.VisualRepresentation)}");
|
||||
}
|
||||
_objectManager.SelectObject(newObj);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
}
|
||||
|
||||
// Forzar otra actualización del layout antes de actualizar visuales
|
||||
ImagenEnTrabajoCanvas.UpdateLayout();
|
||||
|
||||
// Actualizar SelectedItemOsList si hay objetos pegados
|
||||
if (newlyPastedObjects.Count > 0)
|
||||
{
|
||||
if (DataContext is MainViewModel vm)
|
||||
{
|
||||
Console.WriteLine($"Error general al seleccionar objetos pegados: {ex.Message}");
|
||||
Console.WriteLine($"Stack trace: {ex.StackTrace}");
|
||||
vm.SelectedItemOsList = newlyPastedObjects.LastOrDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
viewModel.HasUnsavedChanges = true;
|
||||
}
|
||||
|
||||
// Actualizar visuales de selección
|
||||
_objectManager.UpdateSelectionVisuals();
|
||||
|
||||
Console.WriteLine($"Pegados y seleccionados {newlyPastedObjects.Count} objeto(s)");
|
||||
}));
|
||||
|
||||
Console.WriteLine($"Pegados {newlyPastedObjects.Count} objeto(s) desde el portapapeles");
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
</UserControl.DataContext>
|
||||
<Grid>
|
||||
<Grid.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}" />
|
||||
<RotateTransform Angle="{Binding Angulo}"
|
||||
CenterX="{Binding RenderTransformCenterX}"
|
||||
CenterY="{Binding RenderTransformCenterY}" />
|
||||
</Grid.RenderTransform>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
|
|
|
@ -307,6 +307,34 @@ namespace CtrEditor.ObjetosSim
|
|||
[property: Category("Appearance:")]
|
||||
private bool showPlate;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Use horizontal center as pivot point for rotation")]
|
||||
[property: Category("Pivot:")]
|
||||
private bool pivotCenterX;
|
||||
|
||||
[ObservableProperty]
|
||||
[property: Description("Use vertical center as pivot point for rotation")]
|
||||
[property: Category("Pivot:")]
|
||||
private bool pivotCenterY;
|
||||
|
||||
partial void OnPivotCenterXChanged(bool value)
|
||||
{
|
||||
// Notificar cambio de pivot para actualizar objetos conectados
|
||||
OnPropertyChanged(nameof(PivotCenterX));
|
||||
// Notificar cambios en las propiedades de pivot para el RenderTransform
|
||||
OnPropertyChanged(nameof(RenderTransformCenterX));
|
||||
OnPropertyChanged(nameof(RenderTransformCenterY));
|
||||
}
|
||||
|
||||
partial void OnPivotCenterYChanged(bool value)
|
||||
{
|
||||
// Notificar cambio de pivot para actualizar objetos conectados
|
||||
OnPropertyChanged(nameof(PivotCenterY));
|
||||
// Notificar cambios en las propiedades de pivot para el RenderTransform
|
||||
OnPropertyChanged(nameof(RenderTransformCenterX));
|
||||
OnPropertyChanged(nameof(RenderTransformCenterY));
|
||||
}
|
||||
|
||||
public osFramePlate()
|
||||
{
|
||||
Ancho = 0.5f;
|
||||
|
@ -318,6 +346,23 @@ namespace CtrEditor.ObjetosSim
|
|||
ShowPlate = true; // Default value
|
||||
}
|
||||
|
||||
public override void AnchoChanged(float value)
|
||||
{
|
||||
base.AnchoChanged(value);
|
||||
OnPropertyChanged(nameof(RenderTransformCenterX));
|
||||
}
|
||||
|
||||
public override void AltoChanged(float value)
|
||||
{
|
||||
base.AltoChanged(value);
|
||||
OnPropertyChanged(nameof(RenderTransformCenterY));
|
||||
}
|
||||
|
||||
partial void OnAlto_TituloChanged(float value)
|
||||
{
|
||||
OnPropertyChanged(nameof(RenderTransformCenterY));
|
||||
}
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
base.ucLoaded();
|
||||
|
@ -335,6 +380,63 @@ namespace CtrEditor.ObjetosSim
|
|||
// eliminar el objeto de simulacion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calcula el punto de pivot basado en los checkboxes PivotCenterX y PivotCenterY
|
||||
/// </summary>
|
||||
/// <returns>Punto de pivot en coordenadas absolutas</returns>
|
||||
public (float X, float Y) GetPivotPoint()
|
||||
{
|
||||
float pivotX = Left + (PivotCenterX ? Ancho / 2 : 0);
|
||||
float pivotY = Top + (PivotCenterY ? Alto / 2 : 0);
|
||||
return (pivotX, pivotY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Centro X para el RenderTransform en píxeles del control
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public double RenderTransformCenterX
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PivotCenterX)
|
||||
{
|
||||
// Centro horizontal del rectángulo principal
|
||||
return PixelToMeter.Instance.calc.MetersToPixels(Ancho) / 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Left del rectángulo principal (0)
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Centro Y para el RenderTransform en píxeles del control
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public double RenderTransformCenterY
|
||||
{
|
||||
get
|
||||
{
|
||||
// Altura del título y del rectángulo principal
|
||||
double titleHeight = PixelToMeter.Instance.calc.MetersToPixels(Alto_Titulo);
|
||||
double frameHeight = PixelToMeter.Instance.calc.MetersToPixels(Alto);
|
||||
|
||||
if (PivotCenterY)
|
||||
{
|
||||
// Centro vertical de todo el control (título + rectángulo)
|
||||
return (titleHeight + frameHeight) / 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Top absoluto del control (0)
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class ucFramePlate : UserControl, IDataContainer
|
||||
|
|
|
@ -51,6 +51,12 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
partial void OnDiametroChanged(float value)
|
||||
{
|
||||
// Asegurar que el diámetro sea al menos 0.01m para evitar errores en la simulación
|
||||
if (value < 0.01f)
|
||||
{
|
||||
diametro = 0.01f;
|
||||
return;
|
||||
}
|
||||
SimGeometria?.SetDiameter(Diametro);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,12 @@ namespace CtrEditor.ObjetosSim
|
|||
TiempoRestante -= elapsedMilliseconds / 1000.0f;
|
||||
if (TiempoRestante <= 0)
|
||||
{
|
||||
// Validar que el diámetro sea al menos 0.01m para evitar errores en la simulación
|
||||
if (Diametro_botella < 0.01f)
|
||||
{
|
||||
Diametro_botella = 0.01f;
|
||||
}
|
||||
|
||||
var X = Left + OffsetLeftSalida;
|
||||
var Y = Top + OffsetTopSalida;
|
||||
|
||||
|
|
|
@ -313,6 +313,16 @@ namespace CtrEditor.ObjetosSim
|
|||
[property: Hidden]
|
||||
private float framePlate_InitialAngle;
|
||||
|
||||
[JsonIgnore]
|
||||
[ObservableProperty]
|
||||
[property: Hidden]
|
||||
private float framePlate_PivotX;
|
||||
|
||||
[JsonIgnore]
|
||||
[ObservableProperty]
|
||||
[property: Hidden]
|
||||
private float framePlate_PivotY;
|
||||
|
||||
partial void OnGroup_FramePanelChanged(string value)
|
||||
{
|
||||
if (FramePlate != null)
|
||||
|
@ -325,9 +335,12 @@ 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;
|
||||
// Calcular punto de pivot y posición relativa inicial
|
||||
var pivotPoint = FramePlate.GetPivotPoint();
|
||||
FramePlate_PivotX = pivotPoint.X;
|
||||
FramePlate_PivotY = pivotPoint.Y;
|
||||
FramePlate_RelativeX = Left - FramePlate_PivotX;
|
||||
FramePlate_RelativeY = Top - FramePlate_PivotY;
|
||||
FramePlate_InitialAngle = FramePlate.Angulo;
|
||||
}
|
||||
}
|
||||
|
@ -337,6 +350,8 @@ namespace CtrEditor.ObjetosSim
|
|||
FramePlate_RelativeX = 0;
|
||||
FramePlate_RelativeY = 0;
|
||||
FramePlate_InitialAngle = 0;
|
||||
FramePlate_PivotX = 0;
|
||||
FramePlate_PivotY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,8 +381,17 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
if (e.PropertyName == nameof(osFramePlate.Angulo))
|
||||
{
|
||||
UpdateOrbitalPosition();
|
||||
// Primero actualizar el ángulo del objeto
|
||||
Angulo += ((osFramePlate)sender).offsetAngulo;
|
||||
// Luego actualizar la posición orbital con el ángulo ya actualizado
|
||||
UpdateOrbitalPosition();
|
||||
}
|
||||
|
||||
if (e.PropertyName == nameof(osFramePlate.PivotCenterX) ||
|
||||
e.PropertyName == nameof(osFramePlate.PivotCenterY))
|
||||
{
|
||||
// Cuando cambia el pivot, recalcular posición relativa
|
||||
RecalculateRelativePositionForNewPivot();
|
||||
}
|
||||
|
||||
if (e.PropertyName == nameof(osFramePlate.Zindex_FramePlate))
|
||||
|
@ -381,6 +405,9 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
if (FramePlate == null) return;
|
||||
|
||||
// Actualizar punto de pivot actual (puede haber cambiado por los checkboxes)
|
||||
var currentPivot = FramePlate.GetPivotPoint();
|
||||
|
||||
// Calcular el ángulo de rotación total desde la posición inicial
|
||||
float deltaAngle = FramePlate.Angulo - FramePlate_InitialAngle;
|
||||
|
||||
|
@ -395,10 +422,18 @@ namespace CtrEditor.ObjetosSim
|
|||
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;
|
||||
// Calcular nueva posición absoluta usando el punto de pivot actual
|
||||
float newLeft = currentPivot.X + rotatedX;
|
||||
float newTop = currentPivot.Y + rotatedY;
|
||||
|
||||
// Actualizar directamente los campos sin disparar eventos de cambio
|
||||
SetProperty(ref left, newLeft);
|
||||
SetProperty(ref top, newTop);
|
||||
|
||||
// Forzar actualización de la posición visual
|
||||
ActualizarLeftTop();
|
||||
|
||||
// Llamar a OnMoveResizeRotate para actualizar la física
|
||||
OnMoveResizeRotate();
|
||||
}
|
||||
|
||||
|
@ -407,13 +442,16 @@ namespace CtrEditor.ObjetosSim
|
|||
// Solo actualizar si está conectado a un FramePlate y el movimiento NO viene del FramePlate
|
||||
if (FramePlate != null && !isUpdatingFromFramePlate)
|
||||
{
|
||||
// Obtener punto de pivot actual
|
||||
var currentPivot = FramePlate.GetPivotPoint();
|
||||
|
||||
// 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;
|
||||
// Calcular la posición relativa actual respecto al pivot del FramePlate
|
||||
float currentRelativeX = Left - currentPivot.X;
|
||||
float currentRelativeY = Top - currentPivot.Y;
|
||||
|
||||
// Si el FramePlate está rotado, necesitamos "desrotar" la posición para obtener
|
||||
// la posición relativa en el sistema de coordenadas original
|
||||
|
@ -425,6 +463,34 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
private void RecalculateRelativePositionForNewPivot()
|
||||
{
|
||||
if (FramePlate == null) return;
|
||||
|
||||
// Obtener posición absoluta actual del objeto (antes del cambio de pivot)
|
||||
float currentLeft = Left;
|
||||
float currentTop = Top;
|
||||
|
||||
// Obtener nuevo punto de pivot
|
||||
var newPivot = FramePlate.GetPivotPoint();
|
||||
|
||||
// Calcular nueva posición relativa respecto al nuevo pivot
|
||||
// Considerar la rotación actual para obtener posición relativa en sistema original
|
||||
float deltaAngle = FramePlate.Angulo - FramePlate_InitialAngle;
|
||||
float angleRad = deltaAngle * (float)Math.PI / 180.0f;
|
||||
|
||||
// Posición relativa actual respecto al nuevo pivot
|
||||
float currentRelativeX = currentLeft - newPivot.X;
|
||||
float currentRelativeY = currentTop - newPivot.Y;
|
||||
|
||||
// "Desrotar" para obtener coordenadas en el sistema 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)
|
||||
{
|
||||
|
@ -1082,6 +1148,8 @@ namespace CtrEditor.ObjetosSim
|
|||
CanvasSetTopinMeter(Top);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public bool LeerBitTag(string Tag)
|
||||
{
|
||||
if (this._plc == null) return false;
|
||||
|
|
|
@ -520,6 +520,8 @@ namespace CtrEditor.Simulacion
|
|||
_world = world;
|
||||
ListOnTransports = new List<simBase>();
|
||||
_deferredActions = deferredActions;
|
||||
// Asegurar que el diámetro sea al menos 0.01m para evitar errores
|
||||
diameter = Min(diameter, 0.01f);
|
||||
Radius = diameter / 2;
|
||||
_mass = mass;
|
||||
_activeJoint = null;
|
||||
|
@ -599,6 +601,8 @@ namespace CtrEditor.Simulacion
|
|||
|
||||
public void SetDiameter(float diameter)
|
||||
{
|
||||
// Asegurar que el diámetro sea al menos 0.01m para evitar errores
|
||||
diameter = Min(diameter, 0.01f);
|
||||
Radius = diameter / 2;
|
||||
Create(Body.Position); // Recrear el círculo con el nuevo tamaño
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue