Con ucGuias
This commit is contained in:
parent
643287583a
commit
e23e07b2c2
|
@ -90,16 +90,16 @@ namespace CtrEditor
|
||||||
double topPixels = centerY - (userControl.ActualHeight / 2);
|
double topPixels = centerY - (userControl.ActualHeight / 2);
|
||||||
|
|
||||||
// Establece la posición del UserControl
|
// Establece la posición del UserControl
|
||||||
NuevoOS.LeftPixels = (float)leftPixels;
|
NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels);
|
||||||
NuevoOS.TopPixels = (float)topPixels;
|
NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels);
|
||||||
|
|
||||||
NuevoOS.Inicializado = true;
|
NuevoOS.Inicializado = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Fuerza a Establecer la posición del UserControl
|
// Fuerza a Establecer la posición del UserControl
|
||||||
NuevoOS.LeftPixels = NuevoOS.LeftPixels;
|
NuevoOS.Left = NuevoOS.Left;
|
||||||
NuevoOS.TopPixels = NuevoOS.TopPixels;
|
NuevoOS.Top = NuevoOS.Top;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suscribirse a eventos de mouse para marcar el Control
|
// Suscribirse a eventos de mouse para marcar el Control
|
||||||
|
|
|
@ -16,6 +16,8 @@ namespace CtrEditor.ObjetosSim
|
||||||
return new ucBotella();
|
return new ucBotella();
|
||||||
if (tipoObjeto == typeof(osTransporteTTop))
|
if (tipoObjeto == typeof(osTransporteTTop))
|
||||||
return new ucTransporteTTop();
|
return new ucTransporteTTop();
|
||||||
|
if (tipoObjeto == typeof(osGuia))
|
||||||
|
return new ucGuia();
|
||||||
|
|
||||||
// Puedes añadir más condiciones para otros tipos
|
// Puedes añadir más condiciones para otros tipos
|
||||||
|
|
||||||
|
@ -28,6 +30,8 @@ namespace CtrEditor.ObjetosSim
|
||||||
return new osBotella();
|
return new osBotella();
|
||||||
if (tipoObjeto == typeof(osTransporteTTop))
|
if (tipoObjeto == typeof(osTransporteTTop))
|
||||||
return new osTransporteTTop();
|
return new osTransporteTTop();
|
||||||
|
if (tipoObjeto == typeof(osGuia))
|
||||||
|
return new osGuia();
|
||||||
|
|
||||||
// Puedes añadir más condiciones para otros tipos
|
// Puedes añadir más condiciones para otros tipos
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
@ -13,6 +14,8 @@ using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
namespace CtrEditor.ObjetosSim
|
namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public interface IosBase
|
public interface IosBase
|
||||||
{
|
{
|
||||||
string Nombre { get; }
|
string Nombre { get; }
|
||||||
|
@ -33,8 +36,6 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public abstract class osBase : INotifyPropertyChanged, IosBase
|
public abstract class osBase : INotifyPropertyChanged, IosBase
|
||||||
{
|
{
|
||||||
public abstract float LeftPixels { get; set; }
|
|
||||||
public abstract float TopPixels { get; set; }
|
|
||||||
public abstract float Left { get; set; }
|
public abstract float Left { get; set; }
|
||||||
public abstract float Top { get; set; }
|
public abstract float Top { get; set; }
|
||||||
|
|
||||||
|
@ -54,6 +55,18 @@ namespace CtrEditor.ObjetosSim
|
||||||
set => _visualRepresentation = value;
|
set => _visualRepresentation = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CanvasSetLeftinMeter(float left)
|
||||||
|
{
|
||||||
|
if (_visualRepresentation != null)
|
||||||
|
Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(left));
|
||||||
|
}
|
||||||
|
public void CanvasSetTopinMeter(float top)
|
||||||
|
{
|
||||||
|
if (_visualRepresentation != null)
|
||||||
|
Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(top));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
|
@ -97,6 +110,22 @@ namespace CtrEditor.ObjetosSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MeterToPixelConverterDbl : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
double meters = (double)value;
|
||||||
|
return (double)PixelToMeter.Instance.calc.MetersToPixels((float)meters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
double pixels = (double)value;
|
||||||
|
return PixelToMeter.Instance.calc.PixelsToMeters((float)pixels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class UnitConverter
|
public class UnitConverter
|
||||||
{
|
{
|
||||||
// La escala representa cuántos metros hay en un píxel
|
// La escala representa cuántos metros hay en un píxel
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
<UserControl x:Class="CtrEditor.ObjetosSim.ucBotella"
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucBotella"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
<Ellipse Height="{Binding DiametroPixels}" Stroke="red" Fill="Gray" Width="{Binding DiametroPixels}"/>
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<local:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Ellipse Height="{Binding Diametro, Converter={StaticResource MeterToPixelConverter}}"
|
||||||
|
Stroke="red" Fill="Gray"
|
||||||
|
Width="{Binding Diametro, Converter={StaticResource MeterToPixelConverter}}"/>
|
||||||
|
|
||||||
</UserControl>
|
</UserControl>
|
|
@ -23,97 +23,57 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public class osBotella : osBase
|
public class osBotella : osBase
|
||||||
{
|
{
|
||||||
private Circle Data = new Circle();
|
private Circle Geometria = new Circle();
|
||||||
|
|
||||||
// Otros datos y métodos relevantes para la simulación
|
// Otros datos y métodos relevantes para la simulación
|
||||||
|
|
||||||
private string _nombre = "Botella";
|
private string _nombre = "Botella";
|
||||||
|
|
||||||
public float Diametro {
|
public float Diametro {
|
||||||
get => Data.Diameter;
|
get => Geometria.Diameter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Diameter = value;
|
Geometria.Diameter = value;
|
||||||
OnPropertyChanged(nameof(Diametro));
|
OnPropertyChanged(nameof(Diametro));
|
||||||
OnPropertyChanged(nameof(DiametroPixels));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public float DiametroPixels
|
|
||||||
{
|
|
||||||
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Diameter);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Diameter = PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
OnPropertyChanged(nameof(Diametro));
|
|
||||||
OnPropertyChanged(nameof(DiametroPixels));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Mass {
|
public float Mass {
|
||||||
get => Data.Mass;
|
get => Geometria.Mass;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Mass = value;
|
Geometria.Mass = value;
|
||||||
OnPropertyChanged(nameof(Mass));
|
OnPropertyChanged(nameof(Mass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Overlap
|
public float Overlap
|
||||||
{
|
{
|
||||||
get => Data.Overlap;
|
get => Geometria.Overlap;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Overlap = value;
|
Geometria.Overlap = value;
|
||||||
OnPropertyChanged(nameof(Overlap));
|
OnPropertyChanged(nameof(Overlap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override float LeftPixels
|
|
||||||
{
|
|
||||||
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Left);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Left = PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
if (_visualRepresentation != null)
|
|
||||||
Canvas.SetLeft(_visualRepresentation, value);
|
|
||||||
OnPropertyChanged(nameof(LeftPixels));
|
|
||||||
OnPropertyChanged(nameof(Left));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override float TopPixels
|
|
||||||
{
|
|
||||||
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Top);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Top = PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
if (_visualRepresentation != null)
|
|
||||||
Canvas.SetTop(_visualRepresentation,value);
|
|
||||||
OnPropertyChanged(nameof(TopPixels));
|
|
||||||
OnPropertyChanged(nameof(Top));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override float Left
|
public override float Left
|
||||||
{
|
{
|
||||||
get => Data.Left;
|
get => Geometria.Left;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Left = value;
|
Geometria.Left = value;
|
||||||
if (_visualRepresentation != null)
|
CanvasSetLeftinMeter(value);
|
||||||
Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
|
||||||
OnPropertyChanged(nameof(LeftPixels));
|
|
||||||
OnPropertyChanged(nameof(Left));
|
OnPropertyChanged(nameof(Left));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override float Top
|
public override float Top
|
||||||
{
|
{
|
||||||
get => Data.Top;
|
get => Geometria.Top;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Top = value;
|
Geometria.Top = value;
|
||||||
if (_visualRepresentation != null)
|
CanvasSetTopinMeter(value);
|
||||||
Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
|
||||||
OnPropertyChanged(nameof(TopPixels));
|
|
||||||
OnPropertyChanged(nameof(Top));
|
OnPropertyChanged(nameof(Top));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,19 +93,19 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public osBotella()
|
public osBotella()
|
||||||
{
|
{
|
||||||
DiametroPixels = 10;
|
Diametro = 0.10f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||||
{
|
{
|
||||||
simulationManager.circles.Add(Data);
|
simulationManager.circles.Add(Geometria);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateControl()
|
public override void UpdateControl()
|
||||||
{
|
{
|
||||||
Top = Data.Top;
|
Top = Geometria.Top;
|
||||||
Left = Data.Left;
|
Left = Geometria.Left;
|
||||||
Overlap = Data.Overlap;
|
Overlap = Geometria.Overlap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +122,8 @@ namespace CtrEditor.ObjetosSim
|
||||||
{
|
{
|
||||||
if (Datos != null)
|
if (Datos != null)
|
||||||
{
|
{
|
||||||
Datos.LeftPixels = LeftPixels;
|
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||||
Datos.TopPixels = TopPixels;
|
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Rotate(float Angle) { }
|
public void Rotate(float Angle) { }
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucGuia"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<local:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Rectangle Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Fill="Blue">
|
||||||
|
<Rectangle.RenderTransform>
|
||||||
|
<RotateTransform Angle="{Binding Angulo}"/>
|
||||||
|
</Rectangle.RenderTransform>
|
||||||
|
</Rectangle>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,140 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace CtrEditor.ObjetosSim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for ucGuia.xaml
|
||||||
|
/// </summary>
|
||||||
|
public class osGuia : osBase
|
||||||
|
{
|
||||||
|
private string _nombre = "Guia";
|
||||||
|
|
||||||
|
private Line Geometria = new Line();
|
||||||
|
|
||||||
|
public override float Left
|
||||||
|
{
|
||||||
|
get => Geometria.Left;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Geometria.Left = value;
|
||||||
|
CanvasSetLeftinMeter(value);
|
||||||
|
OnPropertyChanged(nameof(Left));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override float Top
|
||||||
|
{
|
||||||
|
get => Geometria.Top;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Geometria.Top = value;
|
||||||
|
CanvasSetTopinMeter(value);
|
||||||
|
OnPropertyChanged(nameof(Top));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Ancho
|
||||||
|
{
|
||||||
|
get => Geometria.Length;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Geometria.Length = value;
|
||||||
|
OnPropertyChanged(nameof(Ancho));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public float Alto
|
||||||
|
{
|
||||||
|
get => Geometria.Width;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Geometria.Width = value;
|
||||||
|
OnPropertyChanged(nameof(Alto));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Angulo
|
||||||
|
{
|
||||||
|
get => Geometria.Angle;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Geometria.Angle = value;
|
||||||
|
OnPropertyChanged(nameof(Angulo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Nombre
|
||||||
|
{
|
||||||
|
get => _nombre;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_nombre != value)
|
||||||
|
{
|
||||||
|
_nombre = value;
|
||||||
|
OnPropertyChanged(nameof(Nombre));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public osGuia()
|
||||||
|
{
|
||||||
|
Ancho = 1;
|
||||||
|
Alto = 0.10f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||||
|
{
|
||||||
|
simulationManager.lines.Add(Geometria);
|
||||||
|
}
|
||||||
|
public override void UpdateControl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class ucGuia : UserControl, IDataContainer
|
||||||
|
{
|
||||||
|
public osBase? Datos { get; set; }
|
||||||
|
|
||||||
|
public ucGuia()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
public void Resize(float width, float height)
|
||||||
|
{
|
||||||
|
if (Datos is osGuia datos)
|
||||||
|
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||||
|
}
|
||||||
|
public void Move(float LeftPixels, float TopPixels)
|
||||||
|
{
|
||||||
|
if (Datos != null)
|
||||||
|
{
|
||||||
|
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||||
|
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Rotate(float Angle)
|
||||||
|
{
|
||||||
|
if (Datos != null)
|
||||||
|
if (Datos is osGuia datos)
|
||||||
|
datos.Angulo = Angle;
|
||||||
|
}
|
||||||
|
public void Highlight(bool State) { }
|
||||||
|
public int ZIndex()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<UserControl x:Class="CtrEditor.ObjetosSim.ucTransporteGuias"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
d:DesignHeight="450" d:DesignWidth="800">
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace CtrEditor.ObjetosSim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for ucTransporteGuias.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class ucTransporteGuias : UserControl
|
||||||
|
{
|
||||||
|
public ucTransporteGuias()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,15 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:CtrEditor"
|
mc:Ignorable="d"
|
||||||
mc:Ignorable="d">
|
xmlns:local="clr-namespace:CtrEditor.ObjetosSim">
|
||||||
|
|
||||||
|
<UserControl.Resources>
|
||||||
|
<local:MeterToPixelConverter x:Key="MeterToPixelConverter"/>
|
||||||
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Rectangle Width="{Binding AnchoPixels}" Height="{Binding AltoPixels}" Fill="Gray">
|
<Rectangle Width="{Binding Ancho, Converter={StaticResource MeterToPixelConverter}}" Height="{Binding Alto, Converter={StaticResource MeterToPixelConverter}}" Fill="Gray">
|
||||||
<Rectangle.RenderTransform>
|
<Rectangle.RenderTransform>
|
||||||
<RotateTransform Angle="{Binding Angulo}"/>
|
<RotateTransform Angle="{Binding Angulo}"/>
|
||||||
</Rectangle.RenderTransform>
|
</Rectangle.RenderTransform>
|
||||||
|
|
|
@ -32,111 +32,60 @@ namespace CtrEditor.ObjetosSim
|
||||||
private float tiempoRampa;
|
private float tiempoRampa;
|
||||||
private bool esMarcha;
|
private bool esMarcha;
|
||||||
|
|
||||||
private Rectangle Data = new Rectangle();
|
private Rectangle Geometria = new Rectangle();
|
||||||
|
|
||||||
public override float LeftPixels
|
|
||||||
{
|
|
||||||
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Left);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Left = PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
if (_visualRepresentation != null )
|
|
||||||
Canvas.SetLeft(_visualRepresentation,value);
|
|
||||||
OnPropertyChanged(nameof(LeftPixels));
|
|
||||||
OnPropertyChanged(nameof(Left));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override float TopPixels
|
|
||||||
{
|
|
||||||
get => PixelToMeter.Instance.calc.MetersToPixels(Data.Top);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Top = PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
if (_visualRepresentation != null)
|
|
||||||
Canvas.SetTop(_visualRepresentation, value);
|
|
||||||
OnPropertyChanged(nameof(TopPixels));
|
|
||||||
OnPropertyChanged(nameof(Top));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override float Left
|
public override float Left
|
||||||
{
|
{
|
||||||
get => Data.Left;
|
get => Geometria.Left;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Left = value;
|
Geometria.Left = value;
|
||||||
if (_visualRepresentation != null)
|
CanvasSetLeftinMeter(value);
|
||||||
Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
|
||||||
OnPropertyChanged(nameof(LeftPixels));
|
|
||||||
OnPropertyChanged(nameof(Left));
|
OnPropertyChanged(nameof(Left));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override float Top
|
public override float Top
|
||||||
{
|
{
|
||||||
get => Data.Top;
|
get => Geometria.Top;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Top = value;
|
Geometria.Top = value;
|
||||||
if (_visualRepresentation != null)
|
CanvasSetTopinMeter(value);
|
||||||
Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
|
||||||
OnPropertyChanged(nameof(TopPixels));
|
|
||||||
OnPropertyChanged(nameof(Top));
|
OnPropertyChanged(nameof(Top));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float Ancho {
|
public float Ancho {
|
||||||
get => Data.Length;
|
get => Geometria.Length;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Length = value;
|
Geometria.Length = value;
|
||||||
OnPropertyChanged(nameof(AnchoPixels));
|
|
||||||
OnPropertyChanged(nameof(Ancho));
|
OnPropertyChanged(nameof(Ancho));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public float Alto {
|
public float Alto {
|
||||||
get => Data.Width;
|
get => Geometria.Width;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Width = value;
|
Geometria.Width = value;
|
||||||
OnPropertyChanged(nameof(AltoPixels));
|
|
||||||
OnPropertyChanged(nameof(Alto));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public float AnchoPixels
|
|
||||||
{
|
|
||||||
get => (float)PixelToMeter.Instance.calc.MetersToPixels(Data.Length);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Length = (float)PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
OnPropertyChanged(nameof(AnchoPixels));
|
|
||||||
OnPropertyChanged(nameof(Ancho));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public float AltoPixels
|
|
||||||
{
|
|
||||||
get => (float)PixelToMeter.Instance.calc.MetersToPixels(Data.Width);
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Data.Width = (float)PixelToMeter.Instance.calc.PixelsToMeters(value);
|
|
||||||
OnPropertyChanged(nameof(AltoPixels));
|
|
||||||
OnPropertyChanged(nameof(Alto));
|
OnPropertyChanged(nameof(Alto));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Angulo
|
public float Angulo
|
||||||
{
|
{
|
||||||
get => Data.Angle;
|
get => Geometria.Angle;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Data.Angle = value;
|
Geometria.Angle = value;
|
||||||
OnPropertyChanged(nameof(Angulo));
|
OnPropertyChanged(nameof(Angulo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public float VelocidadActual
|
public float VelocidadActual
|
||||||
{
|
{
|
||||||
get => Data.Speed;
|
get => Geometria.Speed;
|
||||||
set {
|
set {
|
||||||
Data.Speed = value;
|
Geometria.Speed = value;
|
||||||
OnPropertyChanged(nameof(VelocidadActual));
|
OnPropertyChanged(nameof(VelocidadActual));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,13 +110,13 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public osTransporteTTop()
|
public osTransporteTTop()
|
||||||
{
|
{
|
||||||
AnchoPixels = 100;
|
Ancho = 1;
|
||||||
AltoPixels = 10;
|
Alto = 0.10f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||||
{
|
{
|
||||||
simulationManager.rectangles.Add(Data);
|
simulationManager.rectangles.Add(Geometria);
|
||||||
}
|
}
|
||||||
public override void UpdateControl()
|
public override void UpdateControl()
|
||||||
{
|
{
|
||||||
|
@ -186,14 +135,14 @@ namespace CtrEditor.ObjetosSim
|
||||||
public void Resize(float width, float height)
|
public void Resize(float width, float height)
|
||||||
{
|
{
|
||||||
if (Datos is osTransporteTTop datos)
|
if (Datos is osTransporteTTop datos)
|
||||||
datos.AnchoPixels = width;
|
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||||
}
|
}
|
||||||
public void Move(float LeftPixels, float TopPixels)
|
public void Move(float LeftPixels, float TopPixels)
|
||||||
{
|
{
|
||||||
if (Datos != null)
|
if (Datos != null)
|
||||||
{
|
{
|
||||||
Datos.LeftPixels = LeftPixels;
|
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||||
Datos.TopPixels = TopPixels;
|
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void Rotate(float Angle) {
|
public void Rotate(float Angle) {
|
||||||
|
|
|
@ -76,53 +76,99 @@ public class Circle
|
||||||
if (Speed < 0) Speed = 0; // Evitar que la velocidad sea negativa
|
if (Speed < 0) Speed = 0; // Evitar que la velocidad sea negativa
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Interacción por impacto con otros círculos
|
|
||||||
//foreach (var other in circles)
|
|
||||||
//{
|
|
||||||
// if (this != other && IsColliding(this, other))
|
|
||||||
// {
|
|
||||||
// Vector2 impactDirection = other.position - this.position;
|
|
||||||
// Angle = (float)Math.Atan2(impactDirection.Y, impactDirection.X) * (180 / (float)Math.PI);
|
|
||||||
// Speed = other.Speed; // Asumimos que el círculo receptor adopta la velocidad del impacto
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Ajustar por superposición con otros círculos
|
|
||||||
foreach (var other in circles)
|
|
||||||
{
|
|
||||||
if (this != other && IsColliding(this, other))
|
|
||||||
{
|
|
||||||
AdjustForOverlap(other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cambiar dirección al contacto con líneas
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
if (IsCollidingWithLine(this, line))
|
|
||||||
{
|
|
||||||
float impactAngle = CalculateImpactAngle(this, line);
|
|
||||||
if (impactAngle < 85)
|
|
||||||
{
|
|
||||||
AngleofMovement = line.Angle;
|
|
||||||
}
|
|
||||||
else if (impactAngle > 95)
|
|
||||||
{
|
|
||||||
AngleofMovement = line.Angle + 180; // Movimiento contrario
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Speed = 0; // Cancelación de movimiento
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calcular nueva posición
|
// Calcular nueva posición
|
||||||
Vector2 direction = new Vector2((float)Math.Cos(AngleofMovement * Math.PI / 180), (float)Math.Sin(AngleofMovement * Math.PI / 180));
|
Vector2 direction = new Vector2((float)Math.Cos(AngleofMovement * Math.PI / 180), (float)Math.Sin(AngleofMovement * Math.PI / 180));
|
||||||
Vector2 velocity = direction * Speed * timeStepInSeconds;
|
Vector2 velocity = direction * Speed * timeStepInSeconds;
|
||||||
position += velocity;
|
position += velocity;
|
||||||
|
|
||||||
|
// Ajustar por colisiones con líneas
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
Vector2 movementVector = Vector2FromPolar(Speed, AngleofMovement);
|
||||||
|
Vector2 circleCenter = GetCircleCenter(this);
|
||||||
|
|
||||||
|
// Calcular la nueva posición tentativa del centro del círculo
|
||||||
|
Vector2 newPosition = circleCenter + movementVector * timeStepInSeconds;
|
||||||
|
|
||||||
|
if (LineCircleCollision(newPosition, Diameter / 2, line, out Vector2 collisionPoint))
|
||||||
|
{
|
||||||
|
// Ajustar la posición del centro del círculo y el vector de movimiento
|
||||||
|
AdjustCircleAfterCollision(ref newPosition, ref movementVector, line, collisionPoint, Diameter / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualizar la posición del círculo basada en el nuevo centro
|
||||||
|
Left = newPosition.X - Diameter / 2;
|
||||||
|
Top = newPosition.Y - Diameter / 2;
|
||||||
|
Speed = movementVector.Length();
|
||||||
|
AngleofMovement = PolarAngleFromVector(movementVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 GetCircleCenter(Circle circle)
|
||||||
|
{
|
||||||
|
return new Vector2(circle.Left + circle.Diameter / 2, circle.Top + circle.Diameter / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool LineCircleCollision(Vector2 circleCenter, float radius, Line line, out Vector2 collisionPoint)
|
||||||
|
{
|
||||||
|
// Transformar la línea a un vector con el ángulo rotado
|
||||||
|
float angleRadians = line.Angle * (float)Math.PI / 180;
|
||||||
|
Vector2 lineDirection = new Vector2(
|
||||||
|
(float)Math.Cos(angleRadians),
|
||||||
|
(float)Math.Sin(angleRadians)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calcular los puntos de inicio y fin de la línea
|
||||||
|
Vector2 lineStart = new Vector2(line.Left, line.Top);
|
||||||
|
Vector2 lineEnd = lineStart + lineDirection * line.Length;
|
||||||
|
|
||||||
|
// Encontrar el punto más cercano del centro del círculo a la línea
|
||||||
|
Vector2 lineToCircle = circleCenter - lineStart;
|
||||||
|
float projection = Vector2.Dot(lineToCircle, lineDirection);
|
||||||
|
projection = Math.Clamp(projection, 0, line.Length);
|
||||||
|
Vector2 closestPointOnLine = lineStart + projection * lineDirection;
|
||||||
|
|
||||||
|
// Calcular la distancia entre el círculo y el punto más cercano
|
||||||
|
float distance = Vector2.Distance(circleCenter, closestPointOnLine);
|
||||||
|
collisionPoint = closestPointOnLine;
|
||||||
|
|
||||||
|
// Verificar si hay colisión
|
||||||
|
return distance <= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AdjustCircleAfterCollision(ref Vector2 circlePosition, ref Vector2 movementVector, Line line, Vector2 collisionPoint, float radius)
|
||||||
|
{
|
||||||
|
// Calcular el vector normal de la línea para reflejar la dirección de movimiento del círculo
|
||||||
|
float angleRadians = line.Angle * (float)Math.PI / 180;
|
||||||
|
Vector2 lineNormal = new Vector2(-(float)Math.Sin(angleRadians), (float)Math.Cos(angleRadians));
|
||||||
|
|
||||||
|
// Asegurar que la normal está correctamente orientada hacia fuera de la línea
|
||||||
|
if (Vector2.Dot(lineNormal, circlePosition - collisionPoint) < 0)
|
||||||
|
lineNormal = -lineNormal;
|
||||||
|
|
||||||
|
// Calcular el desplazamiento necesario para separar el círculo de la línea
|
||||||
|
Vector2 displacement = lineNormal * (radius - Vector2.Distance(circlePosition, collisionPoint));
|
||||||
|
circlePosition += displacement;
|
||||||
|
|
||||||
|
// Opcionalmente, ajustar la velocidad si el círculo debe "rebotar" de la línea
|
||||||
|
movementVector = Vector2.Reflect(movementVector, lineNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Vector2 Vector2FromPolar(float speed, float angleDegrees)
|
||||||
|
{
|
||||||
|
float angleRadians = angleDegrees * (float)Math.PI / 180;
|
||||||
|
return new Vector2(
|
||||||
|
speed * (float)Math.Cos(angleRadians),
|
||||||
|
speed * (float)Math.Sin(angleRadians)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float PolarAngleFromVector(Vector2 vector)
|
||||||
|
{
|
||||||
|
return (float)Math.Atan2(vector.Y, vector.X) * 180 / (float)Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void AdjustForOverlap(Circle other)
|
private void AdjustForOverlap(Circle other)
|
||||||
|
@ -165,38 +211,7 @@ public class Circle
|
||||||
return distance <= radiusSum;
|
return distance <= radiusSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsCollidingWithLine(Circle circle, Line line)
|
// Circulos sobre Rectangulos
|
||||||
{
|
|
||||||
Vector2 nearestPoint = NearestPointOnLine(circle.position, line.start, line.end);
|
|
||||||
float distanceToLine = Vector2.Distance(circle.position, nearestPoint);
|
|
||||||
return distanceToLine <= (circle.Diameter / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector2 NearestPointOnLine(Vector2 point, Vector2 lineStart, Vector2 lineEnd)
|
|
||||||
{
|
|
||||||
Vector2 lineVector = lineEnd - lineStart;
|
|
||||||
Vector2 pointVector = point - lineStart;
|
|
||||||
float lineLength = lineVector.Length();
|
|
||||||
float projectedLength = Vector2.Dot(pointVector, lineVector) / lineLength;
|
|
||||||
projectedLength = Math.Max(0, Math.Min(lineLength, projectedLength)); // Clamping to the line segment
|
|
||||||
return lineStart + lineVector * (projectedLength / lineLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float CalculateImpactAngle(Circle circle, Line line)
|
|
||||||
{
|
|
||||||
Vector2 movementDirection = new Vector2((float)Math.Cos(circle.AngleofMovement * Math.PI / 180), (float)Math.Sin(circle.AngleofMovement * Math.PI / 180));
|
|
||||||
Vector2 lineDirection = line.end - line.start;
|
|
||||||
Vector2 lineNormal = new Vector2(-lineDirection.Y, lineDirection.X); // Rotar 90 grados para obtener normal
|
|
||||||
lineNormal = Vector2.Normalize(lineNormal);
|
|
||||||
|
|
||||||
// Calcular ángulo entre el movimiento y la normal de la línea
|
|
||||||
float dotProduct = Vector2.Dot(movementDirection, lineNormal);
|
|
||||||
float angle = (float)Math.Acos(dotProduct) * (180 / (float)Math.PI); // Convertir de radianes a grados
|
|
||||||
|
|
||||||
// Ajustar para obtener el ángulo relativo correcto
|
|
||||||
return angle < 90 ? 90 - angle : angle - 90;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float CalculateOverlapPercentage(Circle circle, Rectangle rectangle)
|
public static float CalculateOverlapPercentage(Circle circle, Rectangle rectangle)
|
||||||
{
|
{
|
||||||
// Convertir el círculo en un cuadrado aproximado.
|
// Convertir el círculo en un cuadrado aproximado.
|
||||||
|
@ -284,37 +299,28 @@ public class Rectangle
|
||||||
|
|
||||||
public class Line
|
public class Line
|
||||||
{
|
{
|
||||||
public Vector2 start;
|
private Vector2 position;
|
||||||
public Vector2 end;
|
|
||||||
|
|
||||||
public float Left
|
public float Left
|
||||||
{
|
{
|
||||||
get { return start.X; }
|
get { return position.X; }
|
||||||
set { start = new Vector2(value, start.Y); UpdateEnd(); }
|
set { position = new Vector2(value, position.Y); }
|
||||||
}
|
}
|
||||||
public float Top
|
public float Top
|
||||||
{
|
{
|
||||||
get { return start.Y; }
|
get { return position.Y; }
|
||||||
set { start = new Vector2(start.X, value); UpdateEnd(); }
|
set { position = new Vector2(position.X, value); }
|
||||||
}
|
}
|
||||||
public float Length { get; set; }
|
public float Length { get; set; }
|
||||||
public float Width { get; set; }
|
public float Width { get; set; }
|
||||||
public float Angle { get; set; } // En grados
|
public float Angle { get; set; } // En grados
|
||||||
|
public float Grip { get; set; } // Friccion por contacto
|
||||||
|
|
||||||
public Line(float left, float top, float length, float width, float angle)
|
public Line(float left = 0, float top = 0, float length = 10, float angle = 0, float grip = 0)
|
||||||
{
|
{
|
||||||
start = new Vector2(left, top);
|
position = new Vector2(left, top);
|
||||||
Length = length;
|
Length = length;
|
||||||
Width = width;
|
|
||||||
Angle = angle;
|
Angle = angle;
|
||||||
UpdateEnd();
|
Grip = grip;
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateEnd()
|
|
||||||
{
|
|
||||||
// Asumiendo que la línea se extiende en el ángulo desde el punto de inicio
|
|
||||||
end = new Vector2(start.X + Length * (float)Math.Cos(Angle * Math.PI / 180),
|
|
||||||
start.Y + Length * (float)Math.Sin(Angle * Math.PI / 180));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue