Primera revision. trabajando en la aplicacion de velocidad sobre los transportes.
This commit is contained in:
parent
2bfd83ef3b
commit
56a2e994a2
|
@ -8,11 +8,27 @@
|
|||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
|
||||
<Compile Remove="Simulacion\GeometrySimulator.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="motor2.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Remove="ObjetosSim\ucTransporteCurva.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="ObjetosSim\ucTransporteCurva.xaml" />
|
||||
<None Include="ObjetosSim\ucTransporteCurva.xaml.cs" />
|
||||
<None Include="Simulacion\GeometrySimulator.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FarseerPhysics" Version="3.5.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.77" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
||||
|
|
|
@ -24,6 +24,7 @@ using System.Windows.Data;
|
|||
using System.Windows;
|
||||
using static System.Resources.ResXFileRef;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Simulacion;
|
||||
|
||||
namespace CtrEditor
|
||||
{
|
||||
|
@ -36,7 +37,7 @@ namespace CtrEditor
|
|||
private ObservableCollection<osBase> _objetosSimulables = new ObservableCollection<osBase>();
|
||||
public PLCViewModel _plcViewModelData;
|
||||
|
||||
private SimulationManager simulationManager = new SimulationManager();
|
||||
public SimulationManagerFP simulationManager = new SimulationManagerFP();
|
||||
|
||||
private readonly DispatcherTimer _timerSimulacion;
|
||||
|
||||
|
@ -63,7 +64,7 @@ namespace CtrEditor
|
|||
ItemDoubleClickCommand = new ParameterizedRelayCommand(ExecuteDoubleClick);
|
||||
|
||||
_timerSimulacion = new DispatcherTimer();
|
||||
_timerSimulacion.Interval = TimeSpan.FromMilliseconds(20); // ajusta el intervalo según sea necesario
|
||||
_timerSimulacion.Interval = TimeSpan.FromMilliseconds(16); // ajusta el intervalo según sea necesario
|
||||
_timerSimulacion.Tick += OnTickSimulacion;
|
||||
|
||||
StartSimulationCommand = new RelayCommand(StartSimulation);
|
||||
|
@ -123,6 +124,11 @@ namespace CtrEditor
|
|||
|
||||
private void StartSimulation()
|
||||
{
|
||||
foreach (var objetoSimulable in ObjetosSimulables)
|
||||
objetoSimulable.UpdateGeometryStart();
|
||||
|
||||
simulationManager.Debug_DrawInitialBodies();
|
||||
|
||||
_timerSimulacion.Start();
|
||||
}
|
||||
|
||||
|
@ -138,7 +144,7 @@ namespace CtrEditor
|
|||
{
|
||||
if (_plcViewModelData.IsConnected)
|
||||
objetoSimulable.UpdatePLC(_plcViewModelData.PLCInterface);
|
||||
objetoSimulable.UpdateGeometry();
|
||||
objetoSimulable.UpdateGeometryStep();
|
||||
}
|
||||
|
||||
simulationManager.Step((float)_timerSimulacion.Interval.TotalMilliseconds);
|
||||
|
@ -259,6 +265,7 @@ namespace CtrEditor
|
|||
foreach (var obj in ObjetosSimulables)
|
||||
{
|
||||
obj.VisualRepresentation = null;
|
||||
obj.simulationManager = null;
|
||||
}
|
||||
// Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter
|
||||
var dataToSerialize = new SimulationData
|
||||
|
@ -328,7 +335,8 @@ namespace CtrEditor
|
|||
// Asignar los datos al UserControl
|
||||
UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager);
|
||||
|
||||
OnUserControlSelected?.Invoke(userControl);
|
||||
OnUserControlSelected?.Invoke(userControl);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -19,6 +19,7 @@ using Label = System.Windows.Controls.Label;
|
|||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||
using TextBox = System.Windows.Controls.TextBox;
|
||||
using UserControl = System.Windows.Controls.UserControl;
|
||||
//using OpenCvSharp;
|
||||
|
||||
|
||||
namespace CtrEditor
|
||||
|
@ -62,6 +63,7 @@ namespace CtrEditor
|
|||
//viewModel.TickSimulacion += MainViewModel_TickSimulacion;
|
||||
viewModel.OnUserControlSelected += AgregarUserControl;
|
||||
viewModel?.LoadInitialData(); // Carga la primera imagen por defecto una vez cargada la ventana principal
|
||||
viewModel.simulationManager.DebugCanvas = ImagenEnTrabajoCanvas;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +74,7 @@ namespace CtrEditor
|
|||
var NuevoOS = dataContainer.Datos;
|
||||
if (!NuevoOS.Inicializado) // Aun no fue inicializado
|
||||
{
|
||||
Random rnd = new Random();
|
||||
// Obtiene el factor de escala
|
||||
var scaleTransform = ImagenEnTrabajoCanvas.LayoutTransform as ScaleTransform;
|
||||
double scaleX = scaleTransform?.ScaleX ?? 1.0;
|
||||
|
@ -94,8 +97,8 @@ namespace CtrEditor
|
|||
double topPixels = centerY - (userControl.ActualHeight / 2);
|
||||
|
||||
// Establece la posición del UserControl
|
||||
NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels);
|
||||
NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels);
|
||||
NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels + (float)(rnd.NextDouble() - 0.5) );
|
||||
NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels + (float)(rnd.NextDouble() - 0.5) );
|
||||
|
||||
NuevoOS.Inicializado = true;
|
||||
}
|
||||
|
@ -117,7 +120,7 @@ namespace CtrEditor
|
|||
|
||||
// Añade el UserControl al Canvas
|
||||
Canvas.SetZIndex(userControl, dataContainer.ZIndex());
|
||||
ImagenEnTrabajoCanvas.Children.Add(userControl);
|
||||
ImagenEnTrabajoCanvas.Children.Add(userControl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,7 +426,7 @@ namespace CtrEditor
|
|||
Source = selectedObject,
|
||||
Mode = BindingMode.TwoWay,
|
||||
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus, // Actualizar solo al perder el foco
|
||||
Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"] // Usar el convertidor
|
||||
//Converter = (FloatToFormattedStringConverter)Resources["floatFormatter"] // Usar el convertidor
|
||||
};
|
||||
|
||||
// Aplicar el convertidor solo a propiedades float
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using CtrEditor.Simulacion;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -20,8 +21,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new ucGuia();
|
||||
if (tipoObjeto == typeof(osTransporteGuias))
|
||||
return new ucTransporteGuias();
|
||||
if (tipoObjeto == typeof(osTransporteCurva))
|
||||
return new ucTransporteCurva();
|
||||
//if (tipoObjeto == typeof(osTransporteCurva))
|
||||
// return new ucTransporteCurva();
|
||||
if (tipoObjeto == typeof(osVMmotorSim ))
|
||||
return new ucVMmotorSim();
|
||||
|
||||
|
@ -40,8 +41,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new osGuia();
|
||||
if (tipoObjeto == typeof(osTransporteGuias))
|
||||
return new osTransporteGuias();
|
||||
if (tipoObjeto == typeof(osTransporteCurva))
|
||||
return new osTransporteCurva();
|
||||
//if (tipoObjeto == typeof(osTransporteCurva))
|
||||
// return new osTransporteCurva();
|
||||
if (tipoObjeto == typeof(osVMmotorSim))
|
||||
return new osVMmotorSim();
|
||||
|
||||
|
@ -62,14 +63,14 @@ namespace CtrEditor.ObjetosSim
|
|||
return instance;
|
||||
}
|
||||
|
||||
public static void AssignDatos(UserControl userControl, osBase datos, SimulationManager simulationManager)
|
||||
public static void AssignDatos(UserControl userControl, osBase datos, SimulationManagerFP simulationManager)
|
||||
{
|
||||
if (userControl is IDataContainer dataContainer)
|
||||
{
|
||||
dataContainer.Datos = datos;
|
||||
userControl.DataContext = datos;
|
||||
datos.VisualRepresentation = userControl;
|
||||
datos.ConnectSimManager(simulationManager);
|
||||
datos.simulationManager = simulationManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,10 @@ using System.Windows.Data;
|
|||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
using System.Windows.Media;
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics.Dynamics;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -23,7 +27,6 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
string Nombre { get; }
|
||||
|
||||
void ConnectSimManager(SimulationManager simulationManager);
|
||||
void UpdateControl();
|
||||
}
|
||||
|
||||
|
@ -48,10 +51,11 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public abstract string Nombre { get; set; }
|
||||
|
||||
public abstract void ConnectSimManager(SimulationManager simulationManager);
|
||||
public abstract void UpdateControl();
|
||||
public abstract void UpdateGeometry();
|
||||
public abstract void UpdateGeometryStart();
|
||||
public abstract void UpdateGeometryStep();
|
||||
public abstract void UpdatePLC(PLCModel plc);
|
||||
public abstract void ucLoaded();
|
||||
|
||||
[JsonIgnore]
|
||||
public UserControl? VisualRepresentation
|
||||
|
@ -59,6 +63,9 @@ namespace CtrEditor.ObjetosSim
|
|||
get => _visualRepresentation;
|
||||
set => _visualRepresentation = value;
|
||||
}
|
||||
[JsonIgnore]
|
||||
public SimulationManagerFP simulationManager;
|
||||
|
||||
|
||||
public void CanvasSetLeftinMeter(float left)
|
||||
{
|
||||
|
@ -84,6 +91,91 @@ namespace CtrEditor.ObjetosSim
|
|||
else return 0f;
|
||||
}
|
||||
|
||||
public (Vector2 TopLeft, Vector2 BottomRight) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect)
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
var _canvasLeft = CanvasGetLeftinMeter();
|
||||
var _canvasTop = CanvasGetTopinMeter();
|
||||
|
||||
// Obtiene la transformada del objeto visual
|
||||
GeneralTransform transform = rect.TransformToAncestor(_visualRepresentation);
|
||||
|
||||
// Obtiene la posición absoluta
|
||||
Point topLeft = transform.Transform(new Point(0, 0));
|
||||
Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
|
||||
|
||||
return (new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y) + _canvasTop),
|
||||
new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)bottomRight.Y) + _canvasTop));
|
||||
}
|
||||
else return (new Vector2(0, 0), new Vector2(0, 0));
|
||||
}
|
||||
|
||||
public (Vector2 Start, Vector2 End) GetCenterLineVectors(System.Windows.Shapes.Rectangle rect)
|
||||
{
|
||||
if (rect == null)
|
||||
return (new Vector2(0, 0), new Vector2(0, 0));
|
||||
|
||||
var _canvasLeft = CanvasGetLeftinMeter();
|
||||
var _canvasTop = CanvasGetTopinMeter();
|
||||
|
||||
var transform = rect.TransformToAncestor(_visualRepresentation);
|
||||
|
||||
// Puntos en coordenadas locales del rectángulo no rotado
|
||||
Point startLocal = new Point(0, rect.ActualHeight / 2);
|
||||
Point endLocal = new Point(rect.ActualWidth, rect.ActualHeight / 2);
|
||||
|
||||
// Transformar estos puntos al sistema de coordenadas del ancestro
|
||||
Point transformedStart = transform.Transform(startLocal);
|
||||
Point transformedEnd = transform.Transform(endLocal);
|
||||
|
||||
// Convierte a unidades de Farseer (metros en este caso)
|
||||
Vector2 start = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedStart.Y) + _canvasTop);
|
||||
Vector2 end = new Vector2(PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.X) + _canvasLeft, PixelToMeter.Instance.calc.PixelsToMeters((float)transformedEnd.Y) + _canvasTop);
|
||||
|
||||
return (start, end);
|
||||
}
|
||||
|
||||
|
||||
public Vector2 GetRectangleCenter(System.Windows.Shapes.Rectangle wpfRect)
|
||||
{
|
||||
var coords = GetRectangleCoordinatesInMeter(wpfRect);
|
||||
|
||||
Vector2 topLeft = coords.TopLeft;
|
||||
Vector2 bottomRight = coords.BottomRight;
|
||||
|
||||
// Calcular el centro, ancho y alto en metros
|
||||
return new Vector2((topLeft.X + bottomRight.X) / 2, (topLeft.Y + bottomRight.Y) / 2);
|
||||
}
|
||||
|
||||
public void UpdateRectangle(simRectangle simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
||||
{
|
||||
if (simRect != null)
|
||||
simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
||||
}
|
||||
|
||||
public simRectangle AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo)
|
||||
{
|
||||
return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo);
|
||||
}
|
||||
|
||||
public void UpdateOrCreateLine(simLine simGuia, System.Windows.Shapes.Rectangle wpfRect)
|
||||
{
|
||||
if (simGuia != null)
|
||||
{
|
||||
var coords = GetCenterLineVectors(wpfRect);
|
||||
|
||||
// Crear o actualizar simRectangle
|
||||
simGuia.Create( coords.Start,coords.End); // asumiendo que el ángulo inicial es 0
|
||||
}
|
||||
}
|
||||
|
||||
public simLine AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect)
|
||||
{
|
||||
var coords = GetCenterLineVectors(wpfRect);
|
||||
return simulationManager.AddLine(coords.Start, coords.End);
|
||||
}
|
||||
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
|
@ -93,7 +185,4 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@ using System.Windows.Media;
|
|||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Numerics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -25,61 +27,88 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public class osBotella : osBase
|
||||
{
|
||||
private Circle Geometria = new Circle();
|
||||
private float _diametro;
|
||||
private float _mass;
|
||||
private Vector2 _centro = new Vector2(); // Centro
|
||||
private string _nombre = "Botella";
|
||||
private simCircle Simulacion_Botella;
|
||||
|
||||
// Otros datos y métodos relevantes para la simulación
|
||||
|
||||
private string _nombre = "Botella";
|
||||
|
||||
public float Diametro {
|
||||
get => Geometria.Diameter;
|
||||
get => _diametro;
|
||||
set
|
||||
{
|
||||
Geometria.Diameter = value;
|
||||
_diametro = value;
|
||||
Simulacion_Botella?.SetDiameter(Diametro);
|
||||
OnPropertyChanged(nameof(Diametro));
|
||||
}
|
||||
}
|
||||
|
||||
public float Mass {
|
||||
get => Geometria.Mass;
|
||||
get => _mass;
|
||||
set
|
||||
{
|
||||
Geometria.Mass = value;
|
||||
_mass = value;
|
||||
Simulacion_Botella?.SetMass(value);
|
||||
OnPropertyChanged(nameof(Mass));
|
||||
}
|
||||
}
|
||||
|
||||
public float Overlap
|
||||
{
|
||||
get => Geometria.Overlap;
|
||||
set
|
||||
{
|
||||
Geometria.Overlap = value;
|
||||
OnPropertyChanged(nameof(Overlap));
|
||||
}
|
||||
}
|
||||
|
||||
public override float Left
|
||||
{
|
||||
get => Geometria.Left;
|
||||
get => _centro.X-Diametro/2;
|
||||
set
|
||||
{
|
||||
Geometria.Left = value;
|
||||
_centro.X = value+Diametro/2;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => Geometria.Top;
|
||||
get => _centro.Y - Diametro / 2;
|
||||
set
|
||||
{
|
||||
Geometria.Top = value;
|
||||
_centro.Y = value + Diametro / 2;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
public float CenterX
|
||||
{
|
||||
get => _centro.X;
|
||||
set
|
||||
{
|
||||
_centro.X = value;
|
||||
CanvasSetLeftinMeter(Left);
|
||||
OnPropertyChanged(nameof(CenterX));
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public float CenterY
|
||||
{
|
||||
get => _centro.Y;
|
||||
set
|
||||
{
|
||||
_centro.Y = value;
|
||||
CanvasSetTopinMeter(Top);
|
||||
OnPropertyChanged(nameof(CenterY));
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
if (Simulacion_Botella != null)
|
||||
{
|
||||
Simulacion_Botella.SetDiameter(Diametro);
|
||||
Simulacion_Botella.SetPosition(CenterX, CenterY);
|
||||
}
|
||||
}
|
||||
|
||||
public override string Nombre
|
||||
{
|
||||
get => _nombre;
|
||||
|
@ -96,25 +125,34 @@ namespace CtrEditor.ObjetosSim
|
|||
public osBotella()
|
||||
{
|
||||
Diametro = 0.10f;
|
||||
Mass = 1;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.circles.Add(Geometria);
|
||||
}
|
||||
public override void UpdateGeometry()
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
|
||||
public override void UpdatePLC(PLCModel plc) { }
|
||||
|
||||
public override void UpdateControl()
|
||||
{
|
||||
Top = Geometria.Top;
|
||||
Left = Geometria.Left;
|
||||
Overlap = Geometria.Overlap;
|
||||
CenterX = Simulacion_Botella.CenterX;
|
||||
CenterY = Simulacion_Botella.CenterY;
|
||||
}
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
Simulacion_Botella = simulationManager.AddCircle(Diametro, _centro, Mass);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class ucBotella : UserControl, IDataContainer
|
||||
|
@ -124,6 +162,11 @@ namespace CtrEditor.ObjetosSim
|
|||
public ucBotella()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
public void Resize(float width, float height) { }
|
||||
public void Move(float LeftPixels, float TopPixels)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</UserControl.Resources>
|
||||
|
||||
<Canvas>
|
||||
<Rectangle 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>
|
||||
<RotateTransform Angle="{Binding Angulo}"/>
|
||||
</Rectangle.RenderTransform>
|
||||
|
|
|
@ -14,6 +14,10 @@ using System.Windows.Navigation;
|
|||
using System.Windows.Shapes;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -22,26 +26,31 @@ namespace CtrEditor.ObjetosSim
|
|||
/// </summary>
|
||||
public class osGuia : osBase
|
||||
{
|
||||
private float _ancho;
|
||||
private float _altoGuia;
|
||||
private float _left;
|
||||
private float _top;
|
||||
private float _angulo;
|
||||
private string _nombre = "Guia";
|
||||
|
||||
private Line Geometria = new Line();
|
||||
private simLine Simulation_Guia;
|
||||
|
||||
public override float Left
|
||||
{
|
||||
get => Geometria.Left;
|
||||
get => _left;
|
||||
set
|
||||
{
|
||||
Geometria.Left = value;
|
||||
_left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => Geometria.Top;
|
||||
get => _top;
|
||||
set
|
||||
{
|
||||
Geometria.Top = value;
|
||||
_top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
|
@ -49,29 +58,29 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public float Ancho
|
||||
{
|
||||
get => Geometria.Length;
|
||||
get => _ancho;
|
||||
set
|
||||
{
|
||||
Geometria.Length = value;
|
||||
_ancho = value;
|
||||
OnPropertyChanged(nameof(Ancho));
|
||||
}
|
||||
}
|
||||
public float AltoGuia
|
||||
{
|
||||
get => Geometria.Width;
|
||||
get => _altoGuia;
|
||||
set
|
||||
{
|
||||
Geometria.Width = value;
|
||||
_altoGuia = value;
|
||||
OnPropertyChanged(nameof(AltoGuia));
|
||||
}
|
||||
}
|
||||
|
||||
public float Angulo
|
||||
{
|
||||
get => Geometria.Angle;
|
||||
get => _angulo;
|
||||
set
|
||||
{
|
||||
Geometria.Angle = value;
|
||||
_angulo = value;
|
||||
OnPropertyChanged(nameof(Angulo));
|
||||
}
|
||||
}
|
||||
|
@ -89,25 +98,37 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
if (_visualRepresentation is ucGuia uc)
|
||||
UpdateOrCreateLine(Simulation_Guia, uc.Guia);
|
||||
}
|
||||
|
||||
public osGuia()
|
||||
{
|
||||
Ancho = 1;
|
||||
AltoGuia = 0.03f;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.lines.Add(Geometria);
|
||||
}
|
||||
public override void UpdateGeometry()
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
public override void UpdateControl()
|
||||
{
|
||||
}
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc) { }
|
||||
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
if (_visualRepresentation is ucGuia uc)
|
||||
Simulation_Guia = AddLine(simulationManager, uc.Guia);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -119,6 +140,11 @@ namespace CtrEditor.ObjetosSim
|
|||
public ucGuia()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
public void Resize(float width, float height)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@ using System.Windows.Navigation;
|
|||
using System.Windows.Shapes;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -24,36 +25,42 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
private string _nombre = "Transporte Guias";
|
||||
|
||||
private float _distance;
|
||||
private float _altoGuia;
|
||||
|
||||
private float frictionCoefficient;
|
||||
private float velMax50hz; // en metros por minuto
|
||||
private float tiempoRampa;
|
||||
private bool esMarcha;
|
||||
private double _distance;
|
||||
private float altoGuia;
|
||||
|
||||
private float left;
|
||||
private float top;
|
||||
private float _ancho;
|
||||
private float _alto;
|
||||
private float _left;
|
||||
private float _top;
|
||||
private float _angulo;
|
||||
private float _velocidadActual;
|
||||
|
||||
private simRectangle? TransporteCentral;
|
||||
private simLine? Guia_Superior;
|
||||
private simLine? Guia_Inferior;
|
||||
|
||||
private Rectangle TransporteCentral = new Rectangle();
|
||||
private Line Guia_Superior = new Line();
|
||||
private Line Guia_Inferior = new Line();
|
||||
|
||||
public override float Left
|
||||
{
|
||||
get => left;
|
||||
get => _left;
|
||||
set
|
||||
{
|
||||
left = value;
|
||||
_left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => top;
|
||||
get => _top;
|
||||
set
|
||||
{
|
||||
top = value;
|
||||
_top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
|
@ -61,53 +68,45 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public float Ancho
|
||||
{
|
||||
get => TransporteCentral.Length;
|
||||
get => _ancho;
|
||||
set
|
||||
{
|
||||
TransporteCentral.Length = value;
|
||||
_ancho = value;
|
||||
OnPropertyChanged(nameof(Ancho));
|
||||
}
|
||||
}
|
||||
public float AltoGuia
|
||||
{
|
||||
get => altoGuia;
|
||||
set
|
||||
{
|
||||
altoGuia = value;
|
||||
OnPropertyChanged(nameof(AltoGuia));
|
||||
}
|
||||
}
|
||||
|
||||
public float Alto
|
||||
{
|
||||
get => TransporteCentral.Width;
|
||||
get => _alto;
|
||||
set
|
||||
{
|
||||
TransporteCentral.Width = value;
|
||||
_alto = value;
|
||||
OnPropertyChanged(nameof(Alto));
|
||||
}
|
||||
}
|
||||
|
||||
public float Angulo
|
||||
{
|
||||
get => TransporteCentral.Angle;
|
||||
get => _angulo;
|
||||
set
|
||||
{
|
||||
TransporteCentral.Angle = value;
|
||||
_angulo = value;
|
||||
OnPropertyChanged(nameof(Angulo));
|
||||
}
|
||||
}
|
||||
|
||||
public float VelocidadActual
|
||||
{
|
||||
get => TransporteCentral.Speed;
|
||||
get => _velocidadActual;
|
||||
set
|
||||
{
|
||||
TransporteCentral.Speed = value;
|
||||
_velocidadActual = value;
|
||||
TransporteCentral?.SetSpeed(value);
|
||||
OnPropertyChanged(nameof(VelocidadActual));
|
||||
}
|
||||
}
|
||||
|
||||
public double Distance
|
||||
public float Distance
|
||||
{
|
||||
get { return _distance; }
|
||||
set
|
||||
|
@ -115,11 +114,21 @@ namespace CtrEditor.ObjetosSim
|
|||
if (_distance != value)
|
||||
{
|
||||
_distance = value;
|
||||
OnPropertyChanged("Distance");
|
||||
OnPropertyChanged(nameof(Distance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float AltoGuia
|
||||
{
|
||||
get => _altoGuia;
|
||||
set
|
||||
{
|
||||
_altoGuia = value;
|
||||
OnPropertyChanged(nameof(AltoGuia));
|
||||
}
|
||||
}
|
||||
|
||||
public override string Nombre
|
||||
{
|
||||
get => _nombre;
|
||||
|
@ -135,50 +144,21 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
ucTransporteGuias ucTG = (ucTransporteGuias)_visualRepresentation;
|
||||
if (ucTG != null)
|
||||
if (_visualRepresentation is ucTransporteGuias uc)
|
||||
{
|
||||
var _canvasLeft = CanvasGetLeftinMeter();
|
||||
var _canvasTop = CanvasGetTopinMeter();
|
||||
UpdateRectangle(TransporteCentral, uc.Transporte, Alto, Ancho, Angulo);
|
||||
UpdateOrCreateLine(Guia_Superior, uc.GuiaSuperior);
|
||||
UpdateOrCreateLine(Guia_Inferior, uc.GuiaInferior) ;
|
||||
|
||||
var coordenadas = GetRectangleCoordinatesInMeter(ucTG.Transporte, ucTG);
|
||||
TransporteCentral.Left = coordenadas.Left + _canvasLeft;
|
||||
TransporteCentral.Top = coordenadas.Top + _canvasTop;
|
||||
|
||||
coordenadas = GetRectangleCoordinatesInMeter(ucTG.GuiaSuperior, ucTG);
|
||||
Guia_Superior.Left = coordenadas.Left + _canvasLeft;
|
||||
Guia_Superior.Top = coordenadas.Top + _canvasTop; ;
|
||||
|
||||
coordenadas = GetRectangleCoordinatesInMeter(ucTG.GuiaInferior, ucTG);
|
||||
Guia_Inferior.Left = coordenadas.Left + _canvasLeft;
|
||||
Guia_Inferior.Top = coordenadas.Top + _canvasTop; ;
|
||||
|
||||
TransporteCentral.Angle = Guia_Superior.Angle = Guia_Inferior.Angle = Angulo;
|
||||
Guia_Superior.Length = Guia_Inferior.Length = Ancho;
|
||||
TransporteCentral.Speed = VelocidadActual;
|
||||
}
|
||||
}
|
||||
|
||||
private (float Left, float Top) GetRectangleCoordinatesInMeter(System.Windows.Shapes.Rectangle rect, ucTransporteGuias ucTG)
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
// Obtiene la transformada del objeto visual
|
||||
GeneralTransform transform = rect.TransformToAncestor(ucTG);
|
||||
|
||||
// Obtiene la posición absoluta
|
||||
Point topLeft = transform.Transform(new Point(0, 0));
|
||||
//Point bottomRight = transform.Transform(new Point(rect.ActualWidth, rect.ActualHeight));
|
||||
return (PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.X), PixelToMeter.Instance.calc.PixelsToMeters((float)topLeft.Y));
|
||||
}
|
||||
else return (0,0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 osTransporteGuias()
|
||||
{
|
||||
|
@ -188,22 +168,35 @@ namespace CtrEditor.ObjetosSim
|
|||
Distance = 0.01f;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.rectangles.Add(TransporteCentral);
|
||||
simulationManager.lines.Add(Guia_Superior);
|
||||
simulationManager.lines.Add(Guia_Inferior);
|
||||
}
|
||||
public override void UpdateGeometry()
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
}
|
||||
public override void UpdateControl()
|
||||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc) { }
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
simulationManager.rectangles.Add(TransporteCentral);
|
||||
simulationManager.lines.Add(Guia_Superior);
|
||||
simulationManager.lines.Add(Guia_Inferior);
|
||||
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
if (_visualRepresentation is ucTransporteGuias uc)
|
||||
{
|
||||
TransporteCentral = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
||||
Guia_Superior = AddLine(simulationManager, uc.GuiaSuperior);
|
||||
Guia_Inferior = AddLine(simulationManager, uc.GuiaInferior);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -215,6 +208,11 @@ namespace CtrEditor.ObjetosSim
|
|||
public ucTransporteGuias()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
public void Resize(float width, float height)
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</UserControl.Resources>
|
||||
|
||||
<Canvas>
|
||||
<Rectangle 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="Gray">
|
||||
<Rectangle.RenderTransform>
|
||||
<RotateTransform Angle="{Binding Angulo}"/>
|
||||
</Rectangle.RenderTransform>
|
||||
|
|
|
@ -1,22 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using System.Numerics;
|
||||
using System.Windows.Markup;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.Siemens;
|
||||
using CtrEditor.Simulacion;
|
||||
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -34,60 +21,72 @@ namespace CtrEditor.ObjetosSim
|
|||
private float tiempoRampa;
|
||||
private bool esMarcha;
|
||||
|
||||
private Rectangle Geometria = new Rectangle();
|
||||
private float _ancho;
|
||||
private float _alto;
|
||||
private float _left;
|
||||
private float _top;
|
||||
private float _angulo;
|
||||
private float _velocidadActual;
|
||||
|
||||
private simRectangle Simulation_Transporte;
|
||||
|
||||
|
||||
public override float Left
|
||||
{
|
||||
get => Geometria.Left;
|
||||
get => _left;
|
||||
set
|
||||
{
|
||||
Geometria.Left = value;
|
||||
_left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => Geometria.Top;
|
||||
get => _top;
|
||||
set
|
||||
{
|
||||
Geometria.Top = value;
|
||||
_top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
public float Ancho {
|
||||
get => Geometria.Length;
|
||||
public float Ancho
|
||||
{
|
||||
get => _ancho;
|
||||
set
|
||||
{
|
||||
Geometria.Length = value;
|
||||
_ancho = value;
|
||||
OnPropertyChanged(nameof(Ancho));
|
||||
}
|
||||
}
|
||||
public float Alto {
|
||||
get => Geometria.Width;
|
||||
public float Alto
|
||||
{
|
||||
get => _alto;
|
||||
set
|
||||
{
|
||||
Geometria.Width = value;
|
||||
_alto = value;
|
||||
OnPropertyChanged(nameof(Alto));
|
||||
}
|
||||
}
|
||||
|
||||
public float Angulo
|
||||
{
|
||||
get => Geometria.Angle;
|
||||
get => _angulo;
|
||||
set
|
||||
{
|
||||
Geometria.Angle = value;
|
||||
_angulo = value;
|
||||
OnPropertyChanged(nameof(Angulo));
|
||||
}
|
||||
}
|
||||
|
||||
public float VelocidadActual
|
||||
{
|
||||
get => Geometria.Speed;
|
||||
get => _velocidadActual;
|
||||
set {
|
||||
Geometria.Speed = value;
|
||||
_velocidadActual = value;
|
||||
Simulation_Transporte?.SetSpeed(value);
|
||||
OnPropertyChanged(nameof(VelocidadActual));
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +104,15 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
if (_visualRepresentation is ucTransporteTTop uc)
|
||||
{
|
||||
UpdateRectangle(Simulation_Transporte, uc.Transporte,Alto,Ancho,Angulo);
|
||||
Simulation_Transporte.Speed = VelocidadActual;
|
||||
}
|
||||
}
|
||||
|
||||
public float FrictionCoefficient { get => frictionCoefficient; set => frictionCoefficient = value; }
|
||||
public float VelMax50hz { get => velMax50hz; set => velMax50hz = value; }
|
||||
public float TiempoRampa { get => tiempoRampa; set => tiempoRampa = value; }
|
||||
|
@ -116,14 +124,13 @@ namespace CtrEditor.ObjetosSim
|
|||
Alto = 0.10f;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.rectangles.Add(Geometria);
|
||||
}
|
||||
public override void UpdateGeometry()
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc) { }
|
||||
|
||||
|
@ -131,6 +138,13 @@ namespace CtrEditor.ObjetosSim
|
|||
public override void UpdateControl()
|
||||
{
|
||||
}
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
if (_visualRepresentation is ucTransporteTTop uc)
|
||||
Simulation_Transporte = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -141,6 +155,11 @@ namespace CtrEditor.ObjetosSim
|
|||
public ucTransporteTTop()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Datos?.ucLoaded();
|
||||
}
|
||||
public void Resize(float width, float height)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@ using System.Windows.Media;
|
|||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using CtrEditor.Simulacion;
|
||||
|
||||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
@ -93,13 +94,13 @@ namespace CtrEditor.ObjetosSim
|
|||
PLC_NumeroMotor = 31;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
}
|
||||
public override void UpdateGeometry()
|
||||
public override void UpdateGeometryStart()
|
||||
{
|
||||
// Se llama antes de la simulacion
|
||||
|
||||
}
|
||||
public override void UpdateGeometryStep()
|
||||
{
|
||||
}
|
||||
public override void UpdatePLC(PLCModel plc) { }
|
||||
|
||||
|
@ -107,6 +108,12 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
|
||||
}
|
||||
public override void ucLoaded()
|
||||
{
|
||||
// El UserControl ya se ha cargado y podemos obtener las coordenadas para
|
||||
// crear el objeto de simulacion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public partial class ucVMmotorSim : UserControl, IDataContainer
|
||||
|
|
|
@ -0,0 +1,387 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using CtrEditor.Convertidores;
|
||||
using CtrEditor.ObjetosSim;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Common;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
using FarseerPhysics.Factories;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OpenCvSharp;
|
||||
using Siemens.Simatic.Simulation.Runtime;
|
||||
using static System.Windows.Forms.DataFormats;
|
||||
using Point = System.Windows.Point;
|
||||
|
||||
namespace CtrEditor.Simulacion
|
||||
{
|
||||
|
||||
public class simRectangle
|
||||
{
|
||||
public Body Body { get; private set; }
|
||||
public float Speed { get; set; } // Velocidad para efectos de cinta transportadora
|
||||
public World _world;
|
||||
|
||||
public simRectangle(World world, float width, float height, Vector2 position, float angle = 0)
|
||||
{
|
||||
_world = world;
|
||||
Create(width, height, position, angle);
|
||||
}
|
||||
|
||||
public float Angle
|
||||
{
|
||||
get { return MathHelper.ToDegrees(Body.Rotation); }
|
||||
set { Body.Rotation = MathHelper.ToRadians(value); }
|
||||
}
|
||||
|
||||
public void SetPosition(float x, float y)
|
||||
{
|
||||
Body.Position = new Vector2(x, y);
|
||||
}
|
||||
|
||||
public void SetSpeed(float speed)
|
||||
{
|
||||
Speed = speed;
|
||||
}
|
||||
|
||||
public void SetDimensions(float width, float height)
|
||||
{
|
||||
// Primero, elimina el fixture antiguo
|
||||
Body.DestroyFixture(Body.FixtureList[0]);
|
||||
|
||||
// Crea un nuevo fixture con las nuevas dimensiones
|
||||
var newShape = new PolygonShape(PolygonTools.CreateRectangle(width / 2, height / 2), 1f);
|
||||
Body.CreateFixture(newShape);
|
||||
}
|
||||
|
||||
public void Create(float width, float height, Vector2 position, float angle = 0)
|
||||
{
|
||||
if (Body != null) {
|
||||
_world.RemoveBody(Body);
|
||||
}
|
||||
Body = BodyFactory.CreateRectangle(_world, width, height, 1f, position);
|
||||
Body.FixtureList[0].IsSensor = true;
|
||||
Body.BodyType = BodyType.Static;
|
||||
Body.Rotation = MathHelper.ToRadians(angle);
|
||||
Body.UserData = this; // Importante para la identificación durante la colisión
|
||||
}
|
||||
|
||||
|
||||
// Otros métodos según sea necesario, como mover, rotar, etc.
|
||||
}
|
||||
|
||||
|
||||
public class simLine
|
||||
{
|
||||
public Body Body { get; private set; }
|
||||
public World _world;
|
||||
|
||||
public simLine(World world, Vector2 start, Vector2 end)
|
||||
{
|
||||
_world = world;
|
||||
Create(start, end);
|
||||
}
|
||||
|
||||
public void Create(Vector2 start, Vector2 end)
|
||||
{
|
||||
if (Body != null)
|
||||
{
|
||||
_world.RemoveBody(Body); // Elimina el cuerpo anterior si existe
|
||||
}
|
||||
Body = BodyFactory.CreateEdge(_world, start, end);
|
||||
Body.BodyType = BodyType.Static;
|
||||
Body.UserData = this; // Importante para la identificación durante la colisión
|
||||
}
|
||||
|
||||
public void UpdateVertices(Vector2 newStart, Vector2 newEnd)
|
||||
{
|
||||
Create(newStart, newEnd); // Recrear la línea con nuevos vértices
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class simCircle
|
||||
{
|
||||
public Body Body { get; private set; }
|
||||
public World _world;
|
||||
private float _radius;
|
||||
private float _mass;
|
||||
|
||||
public simCircle(World world, float diameter, Vector2 position, float mass)
|
||||
{
|
||||
_world = world;
|
||||
_radius = diameter / 2;
|
||||
_mass = mass;
|
||||
Create(position);
|
||||
}
|
||||
|
||||
public float CenterX
|
||||
{
|
||||
get { return Body.Position.X; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public float CenterY
|
||||
{
|
||||
get { return Body.Position.Y; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public Vector2 Center
|
||||
{
|
||||
get { return Body.Position; }
|
||||
}
|
||||
|
||||
public float Mass
|
||||
{
|
||||
get {
|
||||
if (_mass <= 0)
|
||||
_mass = 1;
|
||||
return _mass;
|
||||
}
|
||||
set { _mass = value; }
|
||||
}
|
||||
|
||||
private void Create(Vector2 position)
|
||||
{
|
||||
if (Body != null)
|
||||
{
|
||||
_world.RemoveBody(Body); // Remover el cuerpo anterior si existe
|
||||
}
|
||||
Body = BodyFactory.CreateCircle(_world, _radius, 10f, position);
|
||||
Body.BodyType = BodyType.Dynamic;
|
||||
|
||||
// Restablecer manejador de eventos de colisión
|
||||
Body.OnCollision += HandleCollision;
|
||||
Body.OnSeparation += HandleOnSeparation;
|
||||
|
||||
Body.UserData = this; // Importante para la identificación durante la colisión
|
||||
|
||||
// Configurar la fricción
|
||||
Body.Friction = 0.5f; // Ajustar según sea necesario para tu simulación
|
||||
|
||||
// Configurar amortiguamiento
|
||||
Body.LinearDamping = 0.01f; // Ajustar para controlar la reducción de la velocidad lineal
|
||||
Body.AngularDamping = 1f; // Ajustar para controlar la reducción de la velocidad angular
|
||||
Body.Restitution = 0.2f; // Baja restitución para menos rebote
|
||||
Body.IsBullet = true;
|
||||
}
|
||||
|
||||
private void HandleOnSeparation(Fixture fixtureA, Fixture fixtureB)
|
||||
{
|
||||
Body.LinearDamping = 5f; // Ajustar para controlar la reducción de la velocidad lineal
|
||||
}
|
||||
|
||||
public void SetPosition(float x, float y)
|
||||
{
|
||||
// Usar el ángulo actual, ya que no es relevante para un círculo en este contexto
|
||||
Body.SetTransform(new Vector2(x, y), Body.Rotation);
|
||||
}
|
||||
|
||||
public void SetDiameter(float diameter)
|
||||
{
|
||||
_radius = diameter / 2;
|
||||
Create(Body.Position); // Recrear el círculo con el nuevo tamaño
|
||||
}
|
||||
|
||||
public void SetMass(float mass)
|
||||
{
|
||||
Mass = mass;
|
||||
}
|
||||
|
||||
|
||||
private bool HandleCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
|
||||
{
|
||||
if (fixtureB.Body.UserData is simRectangle)
|
||||
{
|
||||
simRectangle conveyor = fixtureB.Body.UserData as simRectangle;
|
||||
ApplyConveyorEffect(conveyor, fixtureA, contact);
|
||||
return true; // No aplicar respuestas fisicas
|
||||
}
|
||||
return true; // No aplicar respuestas fisicas
|
||||
}
|
||||
|
||||
private void ApplyConveyorEffect(simRectangle conveyor, Fixture circleFixture, FarseerPhysics.Dynamics.Contacts.Contact contact)
|
||||
{
|
||||
// Calcular la velocidad deseada en metros por segundo
|
||||
float speedMetersPerSecond = conveyor.Speed / 60.0f;
|
||||
Vector2 desiredVelocity = new Vector2((float)Math.Cos(conveyor.Body.Rotation), (float)Math.Sin(conveyor.Body.Rotation)) * speedMetersPerSecond;
|
||||
|
||||
// Calcular la fuerza necesaria para alcanzar esa velocidad
|
||||
Vector2 velocityChange = desiredVelocity - circleFixture.Body.LinearVelocity;
|
||||
float timeStep = 1.0f / 60.0f; // Asumiendo 60 Hz de tasa de actualización
|
||||
Vector2 acceleration = velocityChange / timeStep;
|
||||
Vector2 force = acceleration / Mass;
|
||||
|
||||
// Aplicar la fuerza al círculo
|
||||
circleFixture.Body.ApplyForce(force);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public class SimulationManagerFP
|
||||
{
|
||||
private World world;
|
||||
private Canvas simulationCanvas;
|
||||
public List<simCircle> circles;
|
||||
public List<simRectangle> rectangles;
|
||||
public List<simLine> lines;
|
||||
|
||||
public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; }
|
||||
|
||||
public SimulationManagerFP()
|
||||
{
|
||||
world = new World(new Vector2(0,0)); // Vector2.Zero
|
||||
circles = new List<simCircle>();
|
||||
rectangles = new List<simRectangle>();
|
||||
lines = new List<simLine>();
|
||||
}
|
||||
public simCircle AddCircle(float diameter, Vector2 position, float mass)
|
||||
{
|
||||
simCircle circle = new simCircle(world, diameter, position, mass);
|
||||
circles.Add(circle);
|
||||
return circle;
|
||||
}
|
||||
|
||||
|
||||
public simRectangle AddRectangle(float width, float height, Vector2 position, float angle)
|
||||
{
|
||||
simRectangle rectangle = new simRectangle(world, width, height, position, angle);
|
||||
rectangles.Add(rectangle);
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
public simLine AddLine(Vector2 start, Vector2 end)
|
||||
{
|
||||
simLine line = new simLine(world, start, end);
|
||||
lines.Add(line);
|
||||
return line;
|
||||
}
|
||||
|
||||
// Otros métodos para agregar círculos y ejecutar la simulación
|
||||
|
||||
public void Step(float timeStep)
|
||||
{
|
||||
world.Step(timeStep/1000.0f);
|
||||
// Actualiza y gestiona otras lógicas si es necesario
|
||||
}
|
||||
|
||||
public void Debug_DrawInitialBodies()
|
||||
{
|
||||
ClearSimulationShapes();
|
||||
world.Step(0.01f); // Para actualizar la BodyList
|
||||
foreach (Body body in world.BodyList)
|
||||
{
|
||||
foreach (Fixture fixture in body.FixtureList)
|
||||
{
|
||||
DrawShape(fixture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearSimulationShapes()
|
||||
{
|
||||
var simulationShapes = simulationCanvas.Children.OfType<System.Windows.Shapes.Shape>().Where(s => s.Tag as string == "Simulation").ToList();
|
||||
foreach (var shape in simulationShapes)
|
||||
{
|
||||
simulationCanvas.Children.Remove(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawShape(Fixture fixture)
|
||||
{
|
||||
System.Windows.Shapes.Shape shape;
|
||||
switch (fixture.ShapeType)
|
||||
{
|
||||
case ShapeType.Circle:
|
||||
shape = DrawCircle(fixture);
|
||||
break;
|
||||
case ShapeType.Polygon:
|
||||
shape = DrawPolygon(fixture);
|
||||
break;
|
||||
case ShapeType.Edge:
|
||||
shape = DrawEdge(fixture);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
shape.Tag = "Simulation"; // Marcar para simulación
|
||||
Canvas.SetZIndex(shape, 20);
|
||||
simulationCanvas.Children.Add(shape);
|
||||
}
|
||||
|
||||
private float p(float x)
|
||||
{
|
||||
float c = PixelToMeter.Instance.calc.MetersToPixels(x);
|
||||
return c;
|
||||
}
|
||||
|
||||
private System.Windows.Shapes.Shape DrawEdge(Fixture fixture)
|
||||
{
|
||||
EdgeShape edge = fixture.Shape as EdgeShape;
|
||||
Line line = new Line
|
||||
{
|
||||
X1 = p(edge.Vertex1.X + fixture.Body.Position.X ), // Aplicar escala y posición
|
||||
Y1 = p(edge.Vertex1.Y + fixture.Body.Position.Y ),
|
||||
X2 = p(edge.Vertex2.X + fixture.Body.Position.X ),
|
||||
Y2 = p(edge.Vertex2.Y + fixture.Body.Position.Y ),
|
||||
Stroke = Brushes.Black,
|
||||
StrokeThickness = 2
|
||||
};
|
||||
return line;
|
||||
}
|
||||
|
||||
private System.Windows.Shapes.Shape DrawCircle(Fixture fixture)
|
||||
{
|
||||
CircleShape circle = fixture.Shape as CircleShape;
|
||||
Ellipse ellipse = new Ellipse
|
||||
{
|
||||
Width = p(circle.Radius * 2), // Escalado para visualización
|
||||
Height = p(circle.Radius * 2), // Escalado para visualización
|
||||
Stroke = Brushes.Black,
|
||||
StrokeThickness = 2
|
||||
};
|
||||
Canvas.SetLeft(ellipse, p(fixture.Body.Position.X - circle.Radius ));
|
||||
Canvas.SetTop(ellipse, p(fixture.Body.Position.Y - circle.Radius ));
|
||||
return ellipse;
|
||||
}
|
||||
|
||||
private System.Windows.Shapes.Shape DrawPolygon(Fixture fixture)
|
||||
{
|
||||
Polygon polygon = new Polygon { Stroke = Brushes.Black, StrokeThickness = 2 };
|
||||
PolygonShape polyShape = fixture.Shape as PolygonShape;
|
||||
|
||||
float cos = (float)Math.Cos(fixture.Body.Rotation);
|
||||
float sin = (float)Math.Sin(fixture.Body.Rotation);
|
||||
|
||||
foreach (Vector2 vertex in polyShape.Vertices)
|
||||
{
|
||||
// Aplicar la rotación alrededor del origen y luego trasladar
|
||||
float rotatedX = vertex.X * cos - vertex.Y * sin + fixture.Body.Position.X;
|
||||
float rotatedY = vertex.X * sin + vertex.Y * cos + fixture.Body.Position.Y;
|
||||
|
||||
polygon.Points.Add(new Point(p(rotatedX), p(rotatedY)));
|
||||
}
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue