Circle Primitive Added

This commit is contained in:
Evgeny Redikultsev
2023-02-24 22:17:55 +05:00
parent b05782786c
commit 8fecfb931f
37 changed files with 571 additions and 87 deletions

View File

@@ -3,6 +3,7 @@
public enum PrimitiveType
{
Point,
Rectangle
Rectangle,
Circle
}
}

View File

@@ -0,0 +1,56 @@
using StructureHelper.Infrastructure.UI.Converters.Units;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Strings;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Infrastructure.UI.DataContexts
{
public class CircleViewPrimitive : PrimitiveBase, IHasDivision, IHasCenter
{
ICirclePrimitive primitive;
public double Diameter
{ get
{
return primitive.Diameter;
}
set
{
primitive.Diameter = value;
RefreshPlacement();
}
}
public int NdmMinDivision { get; set; }
public double NdmMaxSize { get; set; }
public double PrimitiveLeft => DeltaX - Diameter / 2d;
public double PrimitiveTop => DeltaY - Diameter / 2d;
public CircleViewPrimitive(INdmPrimitive primitive) : base(primitive)
{
if (primitive is not ICirclePrimitive)
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $"\nExpected: {nameof(ICirclePrimitive)}, But was: {nameof(primitive)}");
}
this.primitive = primitive as ICirclePrimitive;
}
public override INdmPrimitive GetNdmPrimitive()
{
return primitive;
}
private void RefreshPlacement()
{
OnPropertyChanged(nameof(Diameter));
OnPropertyChanged(nameof(CenterX));
OnPropertyChanged(nameof(CenterY));
OnPropertyChanged(nameof(PrimitiveLeft));
OnPropertyChanged(nameof(PrimitiveTop));
}
}
}

View File

@@ -19,16 +19,21 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
ObservableCollection<PrimitiveBase> viewItems = new ObservableCollection<PrimitiveBase>();
foreach (var item in primitives)
{
if (item is IPointPrimitive)
{
var point = item as IPointPrimitive;
viewItems.Add(new PointViewPrimitive(point));
}
else if (item is IRectanglePrimitive)
if (item is IRectanglePrimitive)
{
var rect = item as IRectanglePrimitive;
viewItems.Add(new RectangleViewPrimitive(rect));
}
else if (item is ICirclePrimitive)
{
var circle = item as ICirclePrimitive;
viewItems.Add(new CircleViewPrimitive(circle));
}
else if (item is IPointPrimitive)
{
var point = item as IPointPrimitive;
viewItems.Add(new PointViewPrimitive(point));
}
else throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown);
}
return viewItems;

View File

@@ -10,7 +10,7 @@
xmlns:userControls="clr-namespace:StructureHelper.Infrastructure.UI.UserControls"
mc:Ignorable="d">
<StackPanel>
<Ellipse Style="{StaticResource EllipseStyle}" d:DataContext="{d:DesignInstance dataContexts:PointViewPrimitive}">
<Ellipse Style="{StaticResource EllipseStyle}" d:DataContext="{d:DesignInstance dataContexts:PointViewPrimitive}" Tag ="{Binding}">
<Ellipse.ToolTip>
<Grid>
<Grid.ColumnDefinitions>
@@ -43,6 +43,5 @@
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
<userControls:PrimitivePopup Type="Rectangle" IsOpen="{Binding ParamsPanelVisibilty}" d:DataContext="{d:DesignInstance dataContexts:PrimitiveBase}"/>
</StackPanel>
</UserControl>

View File

@@ -52,6 +52,5 @@
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
<userControls:PrimitivePopup IsOpen="{Binding ParamsPanelVisibilty}"/>
</StackPanel>
</UserControl>

View File

@@ -18,6 +18,9 @@
<DataTemplate DataType="{x:Type dataContexts:RectangleViewPrimitive}">
<dataTemplates:RectangleTemplate/>
</DataTemplate>
<DataTemplate DataType="{x:Type dataContexts:CircleViewPrimitive}">
<dataTemplates:EllipseTemplate/>
</DataTemplate>
<DataTemplate DataType="{x:Type dataContexts:PointViewPrimitive}">
<dataTemplates:EllipseTemplate/>
</DataTemplate>
@@ -97,23 +100,24 @@
<ListBox ItemsSource="{Binding HeadMaterials}" ItemTemplate="{StaticResource ColoredItemTemplate}">
</ListBox>
</Expander>
<Expander Header="Geometry" MinWidth="20" DataContext="{Binding PrimitiveLogic}">
<Expander Header="Geometry" MinWidth="20">
<Expander.ContextMenu>
<ContextMenu>
<MenuItem Header="Add">
<Button Content="Add Rectangle" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}"/>
<Button Content="Add Point" Command="{Binding Add}" CommandParameter="{x:Static enums:PrimitiveType.Point}"/>
<Button Content="Add Rectangle" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}"/>
<Button Content="Add Circle" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Circle}"/>
<Button Content="Add Point" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Point}"/>
</MenuItem>
</ContextMenu>
</Expander.ContextMenu>
<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" ItemTemplate="{StaticResource ColoredItemTemplate}">
<ListBox.ContextMenu>
<ContextMenu>
<Button Content="Edit" Command="{Binding Edit}"/>
<Button Content="Copy" Command="{Binding Copy}"/>
<Button Content="Delete" Command="{Binding Delete}"/>
<Button Content="To Foreground" Command="{Binding SetToFront}"/>
<Button Content="To Background" Command="{Binding SetToBack}"/>
<Button Content="Edit" Command="{Binding PrimitiveLogic.Edit}"/>
<Button Content="Copy" Command="{Binding PrimitiveLogic.Copy}"/>
<Button Content="Delete" Command="{Binding PrimitiveLogic.Delete}"/>
<Button Content="To Foreground" Command="{Binding PrimitiveLogic.SetToFront}"/>
<Button Content="To Background" Command="{Binding PrimitiveLogic.SetToBack}"/>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
@@ -152,6 +156,15 @@
</i:Interaction.Triggers>
<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
<Canvas Name="WorkPlane" ClipToBounds="True" Width="{Binding CanvasWidth}" Height="{Binding CanvasHeight}">
<Canvas.ContextMenu>
<ContextMenu>
<MenuItem Header="Add">
<Button Content="Add Rectangle" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Rectangle}"/>
<Button Content="Add Circle" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Circle}"/>
<Button Content="Add Point" Command="{Binding PrimitiveLogic.Add}" CommandParameter="{x:Static enums:PrimitiveType.Point}"/>
</MenuItem>
</ContextMenu>
</Canvas.ContextMenu>
<i:Interaction.Behaviors>
<infrastructure:MouseBehaviour MouseX="{Binding PanelX, Mode=OneWayToSource}" MouseY="{Binding PanelY, Mode=OneWayToSource}"/>
</i:Interaction.Behaviors>
@@ -182,9 +195,9 @@
<Line X1="{Binding YX1}" X2="{Binding YX1}" Y1="0" Y2="{Binding YY2}" Stroke="ForestGreen" StrokeThickness="{Binding AxisLineThickness}"/>
<ItemsControl ItemsSource="{Binding PrimitiveLogic.Items}" d:DataContext="{d:DesignInstance vm:MainViewModel}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
@@ -192,8 +205,18 @@
<Setter Property="Canvas.Left" Value="{Binding PrimitiveLeft}"/>
<Setter Property="Canvas.Top" Value="{Binding PrimitiveTop}"/>
<Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<EventSetter Event="MouseDown" Handler="ContentPresenter_MouseLeftButtonDown"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ContextMenu>
<ContextMenu>
<Button Content="Edit primitive" Command="{Binding PrimitiveLogic.Edit}"/>
<Button Content="Copy" Command="{Binding PrimitiveLogic.Copy}"/>
<Button Content="Delete" Command="{Binding PrimitiveLogic.Delete}"/>
<Button Content="To Foreground" Command="{Binding PrimitiveLogic.SetToFront}"/>
<Button Content="To Background" Command="{Binding PrimitiveLogic.SetToBack}"/>
</ContextMenu>
</ItemsControl.ContextMenu>
</ItemsControl>
</Canvas>
</ScrollViewer>

View File

@@ -1,4 +1,6 @@
using System.Windows;
using System.Windows.Controls;
using StructureHelper.Infrastructure.UI.DataContexts;
using StructureHelper.Services;
using StructureHelper.Services.Primitives;
@@ -6,13 +8,22 @@ namespace StructureHelper.Windows.MainWindow
{
public partial class MainView : Window
{
private MainViewModel viewModel;
public IPrimitiveRepository PrimitiveRepository { get; }
public MainView(IPrimitiveRepository primitiveRepository, MainViewModel viewModel)
{
PrimitiveRepository = primitiveRepository;
DataContext = viewModel;
this.viewModel = viewModel;
DataContext = this.viewModel;
InitializeComponent();
}
private void ContentPresenter_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var contentPresenter = sender as ContentPresenter;
var item = contentPresenter?.Content as PrimitiveBase;
viewModel.PrimitiveLogic.SelectedItem = item;
}
}
}

View File

@@ -191,10 +191,26 @@ namespace StructureHelper.Windows.MainWindow
}
}
public RelayCommand SelectPrimitiveCommand
{
get
{
return selectPrimitive ??
(selectPrimitive = new RelayCommand(obj=>
{
if (obj is PrimitiveBase)
{
SelectedPrimitive = obj as PrimitiveBase;
}
}));
}
}
private double delta = 0.0005;
private ActionsViewModel combinationsLogic;
private IPrimitiveViewModelLogic primitiveLogic;
private RelayCommand showVisualProperty;
private RelayCommand selectPrimitive;
public MainViewModel(MainModel model)
{
@@ -208,7 +224,7 @@ namespace StructureHelper.Windows.MainWindow
XY1 = CanvasHeight / 2d;
YX1 = CanvasWidth / 2d;
YY2 = CanvasHeight;
scaleValue = 400d;
scaleValue = 300d;
LeftButtonUp = new RelayCommand(o =>
{

View File

@@ -28,6 +28,21 @@
</Grid>
</Expander>
</DataTemplate>
<DataTemplate x:Key="CircleProperties">
<Expander Header="Circle" IsExpanded="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="22"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Diameter"/>
<TextBox Grid.Row="0" Grid.Column="1" Margin="1" Text="{Binding Diameter, Converter={StaticResource LengthConverter}, ValidatesOnExceptions=True}"/>
</Grid>
</Expander>
</DataTemplate>
<DataTemplate x:Key="PointProperties">
<Expander Header="Point" IsExpanded="True">
<Grid>

View File

@@ -36,6 +36,7 @@ namespace StructureHelper.Windows.PrimitiveProperiesWindow
this.DataContext = viewModel;
InitializeComponent();
if (primitive is RectangleViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Rectangle); }
else if (primitive is CircleViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Circle); }
else if (primitive is PointViewPrimitive) { AddPrimitiveProperties(PrimitiveType.Point); }
else { throw new Exception("Type of object is unknown"); }
}
@@ -44,6 +45,7 @@ namespace StructureHelper.Windows.PrimitiveProperiesWindow
List<string> names = new List<string>();
if (primitive is IHasDivision) { names.Add("TriangulationProperties");}
if (primitive is RectangleViewPrimitive) { names.Add("RectangleProperties"); }
else if (primitive is CircleViewPrimitive) { names.Add("CircleProperties"); }
else if (primitive is PointViewPrimitive) { names.Add("PointProperties"); }
foreach (var name in names)
{

View File

@@ -19,8 +19,8 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
AxisLineThickness = 2d;
GridLineThickness = 0.25d;
GridSize = 0.05d;
WorkPlainWidth = 2d;
WorkPlainHeight = 1.6d;
WorkPlainWidth = 2.4d;
WorkPlainHeight = 2.0d;
}
}
}

View File

@@ -78,7 +78,15 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
ndmPrimitive = primitive;
viewPrimitive = new PointViewPrimitive(primitive);
}
else if (primitiveType == PrimitiveType.Circle)
{
var primitive = new CirclePrimitive
{
Diameter = 0.5d
};
ndmPrimitive = primitive;
viewPrimitive = new CircleViewPrimitive(primitive);
}
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown + nameof(primitiveType)); }
viewPrimitive.RegisterDeltas(CanvasWidth / 2, CanvasHeight / 2);
repository.Primitives.Add(ndmPrimitive);
@@ -159,6 +167,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections
repository.Primitives.Add(newPrimitive);
PrimitiveBase primitiveBase;
if (newPrimitive is IRectanglePrimitive) { primitiveBase = new RectangleViewPrimitive(newPrimitive as IRectanglePrimitive); }
else if (newPrimitive is ICirclePrimitive) { primitiveBase = new CircleViewPrimitive(newPrimitive as ICirclePrimitive); }
else if (newPrimitive is IPointPrimitive) { primitiveBase = new PointViewPrimitive(newPrimitive as IPointPrimitive); }
else throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown);
primitiveBase.RegisterDeltas(CanvasWidth / 2, CanvasHeight / 2);

View File

@@ -17,7 +17,7 @@ namespace StructureHelper.Windows.ViewModels.PrimitiveTemplates.RCs
{
public IRectangleBeamTemplate Model;
private RectangleShape rectangle => (Model.Shape as RectangleShape);
private RectangleShape rectangle => Model.Shape as RectangleShape;
public Window ParentWindow { get; set; }

View File

@@ -9,7 +9,7 @@
public static string ShapeIsNotCorrect => "#0004: Shape is not valid";
public static string LimitStatesIsNotValid => "#0005: Type of limite state is not valid";
public static string LoadTermIsNotValid => "#0006: Load term is not valid";
public static string IncorrectValue => "#0007: value is not valid";
public static string IncorrectValue => "#0007: Value is not valid";
public static string FileCantBeDeleted => "#0008: File can't be deleted";
public static string FileCantBeSaved => "#0009: File can't be saved";
public static string VisualPropertyIsNotRight => "#0010: VisualPropertyIsNotRight";

View File

@@ -1,6 +1,6 @@
namespace StructureHelperCommon.Models.Shapes
{
public interface ICircle : IShape
public interface ICircleShape : IShape
{
double Diameter { get; set; }
}

View File

@@ -18,5 +18,10 @@ namespace StructureHelperCommon.Services.ShapeServices
target.Height = source.Height;
target.Angle = source.Angle;
}
public static void CopyCircleProperties(ICircleShape source, ICircleShape target)
{
target.Diameter = source.Diameter;
}
}
}

View File

@@ -0,0 +1,61 @@
using StructureHelper.Models.Materials;
using StructureHelperLogics.Models.Primitives;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;
namespace StructureHelperLogics.Models.Templates.CrossSections.RCs
{
public class CircleGeometryLogic : IRCGeometryLogic
{
ICircleBeamTemplate template;
public IEnumerable<IHeadMaterial> HeadMaterials { get; set; }
public CircleGeometryLogic(ICircleBeamTemplate template)
{
this.template = template;
}
public IEnumerable<INdmPrimitive> GetNdmPrimitives()
{
List<INdmPrimitive> primitives = new List<INdmPrimitive>();
primitives.AddRange(GetConcretePrimitives());
primitives.AddRange(GetReinfrocementPrimitives());
return primitives;
}
private IEnumerable<INdmPrimitive> GetConcretePrimitives()
{
var diameter = template.SectionDiameter;
var concreteMaterial = HeadMaterials.ToList()[0];
var primitives = new List<INdmPrimitive>();
var rectangle = new CirclePrimitive() { Diameter = diameter, Name = "Concrete block", HeadMaterial = concreteMaterial };
primitives.Add(rectangle);
return primitives;
}
private IEnumerable<INdmPrimitive> GetReinfrocementPrimitives()
{
var reinforcementMaterial = HeadMaterials.ToList()[1];
var radius = template.SectionDiameter / 2 - template.CoverGap;
var dAngle = 2d * Math.PI / template.BarQuantity;
var barArea = Math.PI* template.BarDiameter* template.BarDiameter / 4d;
var primitives = new List<INdmPrimitive>();
for (int i = 0; i < template.BarQuantity; i++)
{
var angle = i * dAngle;
var x = radius * Math.Sin(angle);
var y = radius * Math.Cos(angle);
var point = new PointPrimitive() { CenterX = x, CenterY = y, Area = barArea, Name = "Left bottom point", HeadMaterial = reinforcementMaterial };
primitives.Add(point);
}
return primitives;
}
}
}

View File

@@ -0,0 +1,20 @@
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.Templates.CrossSections.RCs
{
public interface ICircleBeamTemplate
{
ICircleShape Circle { get; }
double CoverGap { get; set; }
double SectionDiameter { get; set; }
int BarQuantity { get; set; }
double BarDiameter { get; set; }
}
}

View File

@@ -46,7 +46,7 @@ namespace StructureHelperLogics.Models.Templates.CrossSections.RCs
private IEnumerable<INdmPrimitive> GetConcretePrimitives()
{
List<INdmPrimitive> primitives = new List<INdmPrimitive>();
var primitives = new List<INdmPrimitive>();
var rectangle = new RectanglePrimitive(concrete) { Width = width, Height = height, Name = "Concrete block" };
primitives.Add(rectangle);
return primitives;

View File

@@ -0,0 +1,66 @@
using LoaderCalculator.Data.Materials;
using LoaderCalculator.Data.Ndms;
using StructureHelper.Models.Materials;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Services.ShapeServices;
using StructureHelperLogics.NdmCalculations.Triangulations;
using StructureHelperLogics.Services.NdmPrimitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Primitives
{
public class CirclePrimitive : ICirclePrimitive
{
public int Id { get; set; }
public string Name { get; set; }
public double CenterX { get; set; }
public double CenterY { get; set; }
public IHeadMaterial? HeadMaterial { get; set; }
public IStrainTuple UsersPrestrain { get; }
public IStrainTuple AutoPrestrain { get; }
public IVisualProperty VisualProperty { get; }
public double Diameter { get; set; }
public double NdmMaxSize { get; set; }
public int NdmMinDivision { get; set; }
public CirclePrimitive()
{
Name = "New Circle";
NdmMaxSize = 0.01d;
NdmMinDivision = 10;
VisualProperty = new VisualProperty { Opacity = 0.8d };
UsersPrestrain = new StrainTuple();
AutoPrestrain = new StrainTuple();
}
public object Clone()
{
var primitive = new CirclePrimitive();
NdmPrimitivesService.CopyDivisionProperties(this, primitive);
ShapeService.CopyCircleProperties(this, primitive);
return primitive;
}
public IEnumerable<INdm> GetNdms(IMaterial material)
{
var ndms = new List<INdm>();
var options = new CircleTriangulationLogicOptions(this);
var logic = new CircleTriangulationLogic(options);
ndms.AddRange(logic.GetNdmCollection(material));
return ndms;
}
public void Save()
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Primitives
{
public interface ICirclePrimitive : IHasDivisionSize, ICircleShape
{
}
}

View File

@@ -16,7 +16,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
string Name { get; set; }
double CenterX { get; set; }
double CenterY { get; set; }
IHeadMaterial HeadMaterial { get; set; }
IHeadMaterial? HeadMaterial { get; set; }
IStrainTuple UsersPrestrain { get; }
IStrainTuple AutoPrestrain { get; }
//double PrestrainKx { get; set; }

View File

@@ -22,7 +22,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public string Name { get; set; }
public double CenterX { get; set; }
public double CenterY { get; set; }
public IHeadMaterial HeadMaterial { get; set; }
public IHeadMaterial? HeadMaterial { get; set; }
public IStrainTuple UsersPrestrain { get; private set; }
public IStrainTuple AutoPrestrain { get; private set; }
public double NdmMaxSize { get; set; }
@@ -47,7 +47,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public object Clone()
{
RectanglePrimitive primitive = new RectanglePrimitive();
var primitive = new RectanglePrimitive();
NdmPrimitivesService.CopyDivisionProperties(this, primitive);
ShapeService.CopyRectangleProperties(this, primitive);
return primitive;
@@ -55,9 +55,9 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public IEnumerable<INdm> GetNdms(IMaterial material)
{
List<INdm> ndms = new List<INdm>();
var ndms = new List<INdm>();
var options = new RectangleTriangulationLogicOptions(this);
ITriangulationLogic logic = new RectangleTriangulationLogic(options);
var logic = new RectangleTriangulationLogic(options);
ndms.AddRange(logic.GetNdmCollection(material));
return ndms;
}

View File

@@ -0,0 +1,47 @@
using LoaderCalculator.Data.Materials;
using LoaderCalculator.Data.Ndms;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Strings;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
internal class CircleTriangulationLogic : ITriangulationLogic
{
CircleTriangulationLogicOptions options;
public ITriangulationLogicOptions Options { get; private set; }
public CircleTriangulationLogic(ITriangulationLogicOptions options)
{
ValidateOptions(options);
this.options = options as CircleTriangulationLogicOptions;
Options = options;
}
public IEnumerable<INdm> GetNdmCollection(IMaterial material)
{
double diameter = options.Circle.Diameter;
double ndmMaxSize = options.NdmMaxSize;
int ndmMinDivision = options.NdmMinDivision;
var logicOptions = new LoaderCalculator.Triangulations.CircleTriangulationLogicOptions(diameter, ndmMaxSize, ndmMinDivision);
var logic = LoaderCalculator.Triangulations.Triangulation.GetLogicInstance(logicOptions);
var ndmCollection = logic.GetNdmCollection(new LoaderCalculator.Data.Planes.CirclePlane { Material = material });
TriangulationService.CommonTransform(ndmCollection, options);
TriangulationService.SetPrestrain(ndmCollection, options.Prestrain);
return ndmCollection;
}
public void ValidateOptions(ITriangulationLogicOptions options)
{
if (options is not ICircleTriangulationLogicOptions )
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $"\n Expected: {nameof(ICircleTriangulationLogicOptions)}, But was: {nameof(options)}");
}
}
}
}

View File

@@ -0,0 +1,38 @@
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public class CircleTriangulationLogicOptions : ICircleTriangulationLogicOptions
{
public ICircleShape Circle { get; }
public IPoint2D Center { get; }
public double NdmMaxSize { get; }
public int NdmMinDivision { get; }
public IStrainTuple Prestrain { get; set; }
public CircleTriangulationLogicOptions(ICirclePrimitive primitive)
{
Center = new Point2D() { X = primitive.CenterX, Y = primitive.CenterY };
Circle = primitive;
NdmMaxSize = primitive.NdmMaxSize;
NdmMinDivision = primitive.NdmMinDivision;
Prestrain = new StrainTuple
{
Kx = primitive.UsersPrestrain.Kx + primitive.AutoPrestrain.Kx,
Ky = primitive.UsersPrestrain.Ky + primitive.AutoPrestrain.Ky,
EpsZ = primitive.UsersPrestrain.EpsZ + primitive.AutoPrestrain.EpsZ
};
}
}
}

View File

@@ -0,0 +1,18 @@
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
internal interface ICircleTriangulationLogicOptions : IShapeTriangulationLogicOptions
{
/// <summary>
/// Shape
/// </summary>
ICircleShape Circle { get; }
}
}

View File

@@ -6,23 +6,11 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
/// Parameter of triangulation of rectangle part of section
/// Параметры триангуляции прямоугольного участка сечения
/// </summary>
public interface IRectangleTriangulationLogicOptions : ITriangulationLogicOptions
public interface IRectangleTriangulationLogicOptions : IShapeTriangulationLogicOptions
{
/// <summary>
///
/// </summary>
IPoint2D Center { get; }
/// <summary>
///
/// </summary>
IRectangleShape Rectangle { get; }
/// <summary>
/// Maximum size (width or height) of ndm part after triangulation
/// </summary>
double NdmMaxSize { get; }
/// <summary>
/// Minimum quantity of division of side of rectangle after triangulation
/// </summary>
int NdmMinDivision { get; }
}
}

View File

@@ -0,0 +1,25 @@
using StructureHelperCommon.Models.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public interface IShapeTriangulationLogicOptions : ITriangulationLogicOptions
{
/// <summary>
/// Center of shape
/// </summary>
IPoint2D Center { get; }
/// <summary>
/// Maximum size (width or height) of ndm part after triangulation
/// </summary>
double NdmMaxSize { get; }
/// <summary>
/// Minimum quantity of division of side of rectangle after triangulation
/// </summary>
int NdmMinDivision { get; }
}
}

View File

@@ -1,9 +1,9 @@
namespace StructureHelperLogics.NdmCalculations.Triangulations
using StructureHelperCommon.Models.Forces;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public interface ITriangulationLogicOptions
{
double PrestrainKx { get;}
double PrestrainKy { get;}
double PrestrainEpsZ { get;}
IStrainTuple Prestrain { get; set; }
}
}

View File

@@ -25,7 +25,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
List<INdm> ndmCollection = new List<INdm>();
INdm ndm = new Ndm { CenterX = center.X, CenterY = center.Y, Area = area, Material = material };
ndmCollection.Add(ndm);
NdmTransform.SetPrestrain(ndmCollection, new StrainMatrix() { Kx = Options.PrestrainKx, Ky = Options.PrestrainKy, EpsZ = Options.PrestrainEpsZ });
NdmTransform.SetPrestrain(ndmCollection, new StrainMatrix() { Kx = options.Prestrain.Kx, Ky = options.Prestrain.Ky, EpsZ = options.Prestrain.EpsZ });
return ndmCollection;
}

View File

@@ -1,5 +1,6 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Strings;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.Primitives;
using StructureHelperLogics.NdmCalculations.Primitives;
@@ -17,26 +18,27 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
public IPoint2D Center { get; }
/// <inheritdoc />
public double Area { get; }
public IStrainTuple Prestrain { get; set; }
/// <inheritdoc />
public double PrestrainKx { get; }
/// <inheritdoc />
public double PrestrainKy { get; }
/// <inheritdoc />
public double PrestrainEpsZ { get; }
public PointTriangulationLogicOptions(IPoint2D center, double area)
{
Center = center;
Area = area;
Prestrain = new StrainTuple();
}
public PointTriangulationLogicOptions(IPointPrimitive primitive)
{
Center = new Point2D() { X = primitive.CenterX, Y = primitive.CenterY };
Area = primitive.Area;
PrestrainKx = primitive.UsersPrestrain.Kx + primitive.AutoPrestrain.Kx;
PrestrainKy = primitive.UsersPrestrain.Ky + primitive.AutoPrestrain.Ky;
PrestrainEpsZ = primitive.UsersPrestrain.EpsZ + primitive.AutoPrestrain.EpsZ;
Prestrain = new StrainTuple
{
Kx = primitive.UsersPrestrain.Kx + primitive.AutoPrestrain.Kx,
Ky = primitive.UsersPrestrain.Ky + primitive.AutoPrestrain.Ky,
EpsZ = primitive.UsersPrestrain.EpsZ + primitive.AutoPrestrain.EpsZ
};
}
}
}

View File

@@ -4,39 +4,44 @@ using System;
using System.Collections.Generic;
using LoaderCalculator.Data.Ndms.Transformations;
using LoaderCalculator.Data.Matrix;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Strings;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public class RectangleTriangulationLogic : IRectangleTriangulationLogic
{
IRectangleTriangulationLogicOptions options;
public ITriangulationLogicOptions Options { get; }
public IEnumerable<INdm> GetNdmCollection(IMaterial material)
{
IRectangleTriangulationLogicOptions rectangleOptions = Options as IRectangleTriangulationLogicOptions;
double width = rectangleOptions.Rectangle.Width;
double height = rectangleOptions.Rectangle.Height;
double ndmMaxSize = rectangleOptions.NdmMaxSize;
int ndmMinDivision = rectangleOptions.NdmMinDivision;
double width = options.Rectangle.Width;
double height = options.Rectangle.Height;
double ndmMaxSize = options.NdmMaxSize;
int ndmMinDivision = options.NdmMinDivision;
LoaderCalculator.Triangulations.RectangleTriangulationLogicOptions logicOptions = new LoaderCalculator.Triangulations.RectangleTriangulationLogicOptions(width, height, ndmMaxSize, ndmMinDivision);
var logic = LoaderCalculator.Triangulations.Triangulation.GetLogicInstance(logicOptions);
var ndmCollection = logic.GetNdmCollection(new LoaderCalculator.Data.Planes.RectangularPlane { Material = material });
double dX = rectangleOptions.Center.X;
double dY = rectangleOptions.Center.Y;
NdmTransform.Move(ndmCollection, dX, dY);
double angle = rectangleOptions.Rectangle.Angle;
TriangulationService.CommonTransform(ndmCollection, options);
double angle = options.Rectangle.Angle;
NdmTransform.Rotate(ndmCollection, angle);
NdmTransform.SetPrestrain(ndmCollection, new StrainMatrix() { Kx = Options.PrestrainKx, Ky = Options.PrestrainKy, EpsZ = Options.PrestrainEpsZ });
TriangulationService.SetPrestrain(ndmCollection, options.Prestrain);
return ndmCollection;
}
public void ValidateOptions(ITriangulationLogicOptions options)
{
throw new NotImplementedException();
if (options is not IRectangleTriangulationLogicOptions)
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $"\n Expected: {nameof(IRectangleTriangulationLogicOptions)}, But was: {nameof(options)}");
}
}
public RectangleTriangulationLogic(ITriangulationLogicOptions options)
{
ValidateOptions(options);
this.options = options as IRectangleTriangulationLogicOptions;
Options = options;
}
}

View File

@@ -1,6 +1,7 @@
using System;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Strings;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.Primitives;
using StructureHelperLogics.NdmCalculations.Primitives;
@@ -19,11 +20,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
/// <inheritdoc />
public int NdmMinDivision { get; }
/// <inheritdoc />
public double PrestrainKx { get;}
/// <inheritdoc />
public double PrestrainKy { get; }
/// <inheritdoc />
public double PrestrainEpsZ { get;}
public IStrainTuple Prestrain { get; set; }
public RectangleTriangulationLogicOptions(IPoint2D center, IRectangleShape rectangle, double ndmMaxSize, int ndmMinDivision)
{
@@ -31,6 +28,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
Rectangle = rectangle;
NdmMaxSize = ndmMaxSize;
NdmMinDivision = ndmMinDivision;
Prestrain = new StrainTuple();
}
public RectangleTriangulationLogicOptions(IRectanglePrimitive primitive)
@@ -39,9 +37,12 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
Rectangle = primitive;
NdmMaxSize = primitive.NdmMaxSize;
NdmMinDivision = primitive.NdmMinDivision;
PrestrainKx = primitive.UsersPrestrain.Kx + primitive.AutoPrestrain.Kx;
PrestrainKy = primitive.UsersPrestrain.Ky + primitive.AutoPrestrain.Ky;
PrestrainEpsZ = primitive.UsersPrestrain.EpsZ + primitive.AutoPrestrain.EpsZ;
Prestrain = new StrainTuple
{
Kx = primitive.UsersPrestrain.Kx + primitive.AutoPrestrain.Kx,
Ky = primitive.UsersPrestrain.Ky + primitive.AutoPrestrain.Ky,
EpsZ = primitive.UsersPrestrain.EpsZ + primitive.AutoPrestrain.EpsZ
};
}
}
}

View File

@@ -0,0 +1,28 @@
using LoaderCalculator.Data.Matrix;
using LoaderCalculator.Data.Ndms;
using LoaderCalculator.Data.Ndms.Transformations;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.Design.AxImporter;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
internal static class TriangulationService
{
public static void SetPrestrain(IEnumerable<INdm> ndmCollection, IStrainTuple strainTuple)
{
NdmTransform.SetPrestrain(ndmCollection, new StrainMatrix() { Kx = strainTuple.Kx, Ky = strainTuple.Kx, EpsZ = strainTuple.Kx });
}
public static void CommonTransform(IEnumerable<INdm> ndmCollection, IShapeTriangulationLogicOptions options)
{
double dX = options.Center.X;
double dY = options.Center.Y;
NdmTransform.Move(ndmCollection, dX, dY);
}
}
}

View File

@@ -46,11 +46,9 @@ namespace StructureHelperLogics.Services.NdmPrimitives
{
//Настройки триангуляции
ITriangulationOptions options = new TriangulationOptions { LimiteState = limitState, CalcTerm = calcTerm };
//Формируем коллекцию элементарных участков для расчета в библитеке (т.е. выполняем триангуляцию)
List<INdm> ndmCollection = new List<INdm>();
ndmCollection.AddRange(Triangulation.GetNdms(primitives, options));
return ndmCollection;
}
}

View File

@@ -21,14 +21,47 @@ namespace StructureHelperTests.FunctionalTests.Ndms.SteelSections
[TestCase(0.3, 0.6, 4e8, 0, 0, -1800000, 0d, 0d, -5e-5d)]
[TestCase(0.3, 0.6, 4e8, 7000000, 0, 0, 0.0065882684745345067d, 0d, 0d)]
//[TestCase(0.3, 0.6, 6e8, 10000000, 0, 0, 0.010485801788961743d, 0d, -0.00011114996218404612d)]
public void Run_ShouldPass(double width, double height, double strength, double mx, double my, double nz, double expectedKx, double expectedKy, double expectedEpsilonZ)
public void Run_ShouldPass_Rectangle(double width, double height, double strength, double mx, double my, double nz, double expectedKx, double expectedKy, double expectedEpsilonZ)
{
//Arrange
var headMaterial = HeadMaterialFactory.GetHeadMaterial(HeadmaterialType.Reinforecement400, CodeTypes.EuroCode_2_1990);
ITriangulationOptions options = new TriangulationOptions { LimiteState = LimitStates.ULS, CalcTerm = CalcTerms.ShortTerm };
INdmPrimitive primitive = new RectanglePrimitive { CenterX = 0, CenterY = 0, Width = width, Height = height, HeadMaterial = headMaterial, NdmMaxSize = 1, NdmMinDivision = 100 };
List<INdmPrimitive> primitives = new List<INdmPrimitive>();
primitives.Add(primitive);
var options = new TriangulationOptions { LimiteState = LimitStates.ULS, CalcTerm = CalcTerms.ShortTerm };
var primitive = new RectanglePrimitive { CenterX = 0, CenterY = 0, Width = width, Height = height, HeadMaterial = headMaterial, NdmMaxSize = 1, NdmMinDivision = 100 };
var primitives = new List<INdmPrimitive>() { primitive};
var ndmCollection = Triangulation.GetNdms(primitives, options);
var loaderData = new LoaderOptions
{
Preconditions = new Preconditions
{
ConditionRate = 0.01,
MaxIterationCount = 100,
StartForceMatrix = new ForceMatrix { Mx = mx, My = my, Nz = nz }
},
NdmCollection = ndmCollection
};
var calculator = new Calculator();
//Act
calculator.Run(loaderData, new CancellationToken());
var results = calculator.Result;
//Assert
Assert.NotNull(results);
var strainMatrix = results.StrainMatrix;
Assert.NotNull(strainMatrix);
Assert.AreEqual(expectedKx, strainMatrix.Kx, ExpectedProcessor.GetAccuracyForExpectedValue(expectedKx));
Assert.AreEqual(expectedKy, strainMatrix.Ky, ExpectedProcessor.GetAccuracyForExpectedValue(expectedKy));
Assert.AreEqual(expectedEpsilonZ, strainMatrix.EpsZ, ExpectedProcessor.GetAccuracyForExpectedValue(expectedEpsilonZ));
}
[TestCase(0.3, 4e8, 0, 0, 706850.84713269188d, 0d, 0d, 5e-5d)]
[TestCase(0.3, 4e8, 0, 0, -706850.84713269188d, 0d, 0d, -5e-5d)]
[TestCase(0.3, 4e8, 700000, 0, 0, 0.0076471604851248189d, 0d, 0d)]
public void Run_ShouldPass_Circle(double diameter, double strength, double mx, double my, double nz, double expectedKx, double expectedKy, double expectedEpsilonZ)
{
//Arrange
var headMaterial = HeadMaterialFactory.GetHeadMaterial(HeadmaterialType.Reinforecement400, CodeTypes.EuroCode_2_1990);
var options = new TriangulationOptions { LimiteState = LimitStates.ULS, CalcTerm = CalcTerms.ShortTerm };
var primitive = new CirclePrimitive { CenterX = 0, CenterY = 0, Diameter = diameter, HeadMaterial = headMaterial, NdmMaxSize = 1, NdmMinDivision = 100 };
var primitives = new List<INdmPrimitive>() { primitive };
var ndmCollection = Triangulation.GetNdms(primitives, options);
var loaderData = new LoaderOptions
{