Con ucGuias
This commit is contained in:
parent
643287583a
commit
e23e07b2c2
|
@ -90,16 +90,16 @@ namespace CtrEditor
|
|||
double topPixels = centerY - (userControl.ActualHeight / 2);
|
||||
|
||||
// Establece la posición del UserControl
|
||||
NuevoOS.LeftPixels = (float)leftPixels;
|
||||
NuevoOS.TopPixels = (float)topPixels;
|
||||
NuevoOS.Left = PixelToMeter.Instance.calc.PixelsToMeters((float)leftPixels);
|
||||
NuevoOS.Top = PixelToMeter.Instance.calc.PixelsToMeters((float)topPixels);
|
||||
|
||||
NuevoOS.Inicializado = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fuerza a Establecer la posición del UserControl
|
||||
NuevoOS.LeftPixels = NuevoOS.LeftPixels;
|
||||
NuevoOS.TopPixels = NuevoOS.TopPixels;
|
||||
NuevoOS.Left = NuevoOS.Left;
|
||||
NuevoOS.Top = NuevoOS.Top;
|
||||
}
|
||||
|
||||
// Suscribirse a eventos de mouse para marcar el Control
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new ucBotella();
|
||||
if (tipoObjeto == typeof(osTransporteTTop))
|
||||
return new ucTransporteTTop();
|
||||
if (tipoObjeto == typeof(osGuia))
|
||||
return new ucGuia();
|
||||
|
||||
// Puedes añadir más condiciones para otros tipos
|
||||
|
||||
|
@ -28,6 +30,8 @@ namespace CtrEditor.ObjetosSim
|
|||
return new osBotella();
|
||||
if (tipoObjeto == typeof(osTransporteTTop))
|
||||
return new osTransporteTTop();
|
||||
if (tipoObjeto == typeof(osGuia))
|
||||
return new osGuia();
|
||||
|
||||
// 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.ComponentModel;
|
||||
using System.Globalization;
|
||||
|
@ -13,6 +14,8 @@ using static System.Runtime.InteropServices.JavaScript.JSType;
|
|||
namespace CtrEditor.ObjetosSim
|
||||
{
|
||||
|
||||
|
||||
|
||||
public interface IosBase
|
||||
{
|
||||
string Nombre { get; }
|
||||
|
@ -33,8 +36,6 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
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 Top { get; set; }
|
||||
|
||||
|
@ -54,6 +55,18 @@ namespace CtrEditor.ObjetosSim
|
|||
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;
|
||||
|
||||
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
|
||||
{
|
||||
// La escala representa cuántos metros hay en un píxel
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
<UserControl x:Class="CtrEditor.ObjetosSim.ucBotella"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Ellipse Height="{Binding DiametroPixels}" Stroke="red" Fill="Gray" Width="{Binding DiametroPixels}"/>
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
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>
|
|
@ -23,97 +23,57 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public class osBotella : osBase
|
||||
{
|
||||
private Circle Data = new Circle();
|
||||
private Circle Geometria = new Circle();
|
||||
|
||||
// Otros datos y métodos relevantes para la simulación
|
||||
|
||||
private string _nombre = "Botella";
|
||||
|
||||
public float Diametro {
|
||||
get => Data.Diameter;
|
||||
get => Geometria.Diameter;
|
||||
set
|
||||
{
|
||||
Data.Diameter = value;
|
||||
Geometria.Diameter = value;
|
||||
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 {
|
||||
get => Data.Mass;
|
||||
get => Geometria.Mass;
|
||||
set
|
||||
{
|
||||
Data.Mass = value;
|
||||
Geometria.Mass = value;
|
||||
OnPropertyChanged(nameof(Mass));
|
||||
}
|
||||
}
|
||||
|
||||
public float Overlap
|
||||
{
|
||||
get => Data.Overlap;
|
||||
get => Geometria.Overlap;
|
||||
set
|
||||
{
|
||||
Data.Overlap = value;
|
||||
Geometria.Overlap = value;
|
||||
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
|
||||
{
|
||||
get => Data.Left;
|
||||
get => Geometria.Left;
|
||||
set
|
||||
{
|
||||
Data.Left = value;
|
||||
if (_visualRepresentation != null)
|
||||
Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
||||
OnPropertyChanged(nameof(LeftPixels));
|
||||
Geometria.Left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => Data.Top;
|
||||
get => Geometria.Top;
|
||||
set
|
||||
{
|
||||
Data.Top = value;
|
||||
if (_visualRepresentation != null)
|
||||
Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
||||
OnPropertyChanged(nameof(TopPixels));
|
||||
Geometria.Top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
@ -133,19 +93,19 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public osBotella()
|
||||
{
|
||||
DiametroPixels = 10;
|
||||
Diametro = 0.10f;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.circles.Add(Data);
|
||||
simulationManager.circles.Add(Geometria);
|
||||
}
|
||||
|
||||
public override void UpdateControl()
|
||||
{
|
||||
Top = Data.Top;
|
||||
Left = Data.Left;
|
||||
Overlap = Data.Overlap;
|
||||
Top = Geometria.Top;
|
||||
Left = Geometria.Left;
|
||||
Overlap = Geometria.Overlap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,8 +122,8 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
if (Datos != null)
|
||||
{
|
||||
Datos.LeftPixels = LeftPixels;
|
||||
Datos.TopPixels = TopPixels;
|
||||
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||
}
|
||||
}
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
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>
|
||||
<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>
|
||||
<RotateTransform Angle="{Binding Angulo}"/>
|
||||
</Rectangle.RenderTransform>
|
||||
|
|
|
@ -32,111 +32,60 @@ namespace CtrEditor.ObjetosSim
|
|||
private float tiempoRampa;
|
||||
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
|
||||
{
|
||||
get => Data.Left;
|
||||
get => Geometria.Left;
|
||||
set
|
||||
{
|
||||
Data.Left = value;
|
||||
if (_visualRepresentation != null)
|
||||
Canvas.SetLeft(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
||||
OnPropertyChanged(nameof(LeftPixels));
|
||||
Geometria.Left = value;
|
||||
CanvasSetLeftinMeter(value);
|
||||
OnPropertyChanged(nameof(Left));
|
||||
}
|
||||
}
|
||||
public override float Top
|
||||
{
|
||||
get => Data.Top;
|
||||
get => Geometria.Top;
|
||||
set
|
||||
{
|
||||
Data.Top = value;
|
||||
if (_visualRepresentation != null)
|
||||
Canvas.SetTop(_visualRepresentation, PixelToMeter.Instance.calc.MetersToPixels(value));
|
||||
OnPropertyChanged(nameof(TopPixels));
|
||||
Geometria.Top = value;
|
||||
CanvasSetTopinMeter(value);
|
||||
OnPropertyChanged(nameof(Top));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public float Ancho {
|
||||
get => Data.Length;
|
||||
get => Geometria.Length;
|
||||
set
|
||||
{
|
||||
Data.Length = value;
|
||||
OnPropertyChanged(nameof(AnchoPixels));
|
||||
Geometria.Length = value;
|
||||
OnPropertyChanged(nameof(Ancho));
|
||||
}
|
||||
}
|
||||
public float Alto {
|
||||
get => Data.Width;
|
||||
get => Geometria.Width;
|
||||
set
|
||||
{
|
||||
Data.Width = value;
|
||||
OnPropertyChanged(nameof(AltoPixels));
|
||||
Geometria.Width = value;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
public float Angulo
|
||||
{
|
||||
get => Data.Angle;
|
||||
get => Geometria.Angle;
|
||||
set
|
||||
{
|
||||
Data.Angle = value;
|
||||
Geometria.Angle = value;
|
||||
OnPropertyChanged(nameof(Angulo));
|
||||
}
|
||||
}
|
||||
public float VelocidadActual
|
||||
{
|
||||
get => Data.Speed;
|
||||
get => Geometria.Speed;
|
||||
set {
|
||||
Data.Speed = value;
|
||||
Geometria.Speed = value;
|
||||
OnPropertyChanged(nameof(VelocidadActual));
|
||||
}
|
||||
}
|
||||
|
@ -161,13 +110,13 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
public osTransporteTTop()
|
||||
{
|
||||
AnchoPixels = 100;
|
||||
AltoPixels = 10;
|
||||
Ancho = 1;
|
||||
Alto = 0.10f;
|
||||
}
|
||||
|
||||
public override void ConnectSimManager(SimulationManager simulationManager)
|
||||
{
|
||||
simulationManager.rectangles.Add(Data);
|
||||
simulationManager.rectangles.Add(Geometria);
|
||||
}
|
||||
public override void UpdateControl()
|
||||
{
|
||||
|
@ -186,14 +135,14 @@ namespace CtrEditor.ObjetosSim
|
|||
public void Resize(float width, float height)
|
||||
{
|
||||
if (Datos is osTransporteTTop datos)
|
||||
datos.AnchoPixels = width;
|
||||
datos.Ancho = PixelToMeter.Instance.calc.PixelsToMeters(width);
|
||||
}
|
||||
public void Move(float LeftPixels, float TopPixels)
|
||||
{
|
||||
if (Datos != null)
|
||||
{
|
||||
Datos.LeftPixels = LeftPixels;
|
||||
Datos.TopPixels = TopPixels;
|
||||
Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels);
|
||||
Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels);
|
||||
}
|
||||
}
|
||||
public void Rotate(float Angle) {
|
||||
|
|
|
@ -76,53 +76,99 @@ public class Circle
|
|||
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
|
||||
Vector2 direction = new Vector2((float)Math.Cos(AngleofMovement * Math.PI / 180), (float)Math.Sin(AngleofMovement * Math.PI / 180));
|
||||
Vector2 velocity = direction * Speed * timeStepInSeconds;
|
||||
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)
|
||||
|
@ -165,38 +211,7 @@ public class Circle
|
|||
return distance <= radiusSum;
|
||||
}
|
||||
|
||||
private bool IsCollidingWithLine(Circle circle, Line line)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// Circulos sobre Rectangulos
|
||||
public static float CalculateOverlapPercentage(Circle circle, Rectangle rectangle)
|
||||
{
|
||||
// Convertir el círculo en un cuadrado aproximado.
|
||||
|
@ -284,37 +299,28 @@ public class Rectangle
|
|||
|
||||
public class Line
|
||||
{
|
||||
public Vector2 start;
|
||||
public Vector2 end;
|
||||
|
||||
private Vector2 position;
|
||||
public float Left
|
||||
{
|
||||
get { return start.X; }
|
||||
set { start = new Vector2(value, start.Y); UpdateEnd(); }
|
||||
get { return position.X; }
|
||||
set { position = new Vector2(value, position.Y); }
|
||||
}
|
||||
public float Top
|
||||
{
|
||||
get { return start.Y; }
|
||||
set { start = new Vector2(start.X, value); UpdateEnd(); }
|
||||
get { return position.Y; }
|
||||
set { position = new Vector2(position.X, value); }
|
||||
}
|
||||
public float Length { get; set; }
|
||||
public float Width { get; set; }
|
||||
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;
|
||||
Width = width;
|
||||
Angle = angle;
|
||||
UpdateEnd();
|
||||
}
|
||||
|
||||
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));
|
||||
Grip = grip;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue