Add triangulation of polygon

This commit is contained in:
Evgeny Redikultsev
2025-10-26 22:19:25 +05:00
parent 196dc636bb
commit 09dcf4e7e9
52 changed files with 686 additions and 180 deletions

View File

@@ -67,7 +67,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
var ndms = new List<INdm>();
var options = new CircleTriangulationLogicOptions(this)
{
triangulationOptions = triangulationOptions
TriangulationOptions = triangulationOptions
};
var logic = new CircleTriangulationLogic(options);
ndms.AddRange(logic.GetNdmCollection());

View File

@@ -1,6 +1,5 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Models.Shapes.Logics;
using StructureHelperCommon.Services;
namespace StructureHelperLogics.NdmCalculations.Primitives

View File

@@ -28,6 +28,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives.Logics
if (ReferenceEquals(targetObject, sourceObject)) { return; }
targetObject.Triangulate = sourceObject.Triangulate;
tupleUpdateStrategy.Update(targetObject.UsersPrestrain, sourceObject.UsersPrestrain);
tupleUpdateStrategy.Update(targetObject.AutoPrestrain, sourceObject.AutoPrestrain);
if (UpdateChildren == true)
{
if (sourceObject.HeadMaterial != null)

View File

@@ -46,7 +46,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public IEnumerable<INdm> GetNdms(ITriangulationOptions triangulationOptions)
{
var options = new PointTriangulationLogicOptions(this) { triangulationOptions = triangulationOptions};
var options = new PointTriangulationLogicOptions(this) { TriangulationOptions = triangulationOptions};
var logic = new PointTriangulationLogic(options);
return logic.GetNdmCollection();
}

View File

@@ -78,7 +78,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
{
var options = new RebarTriangulationLogicOptions(this)
{
triangulationOptions = triangulationOptions
TriangulationOptions = triangulationOptions
};
var logic = new RebarTriangulationLogic(options);
var rebar = logic.GetRebarNdm();
@@ -89,7 +89,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
{
var options = new RebarTriangulationLogicOptions(this)
{
triangulationOptions = triangulationOptions
TriangulationOptions = triangulationOptions
};
var logic = new RebarTriangulationLogic(options);
var concrete = logic.GetConcreteNdm();

View File

@@ -53,7 +53,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
var ndms = new List<INdm>();
var options = new RectangleTriangulationLogicOptions(this)
{
triangulationOptions = triangulationOptions
TriangulationOptions = triangulationOptions
};
var logic = new RectangleTriangulationLogic(options);
ndms.AddRange(logic.GetNdmCollection());

View File

@@ -16,11 +16,11 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public string? Name { get; set; } = string.Empty;
public IPoint2D Center { get; set; } = new Point2D();
public IShape Shape => shape;
public INdmElement NdmElement { get; } = new NdmElement(Guid.NewGuid());
public INdmElement NdmElement { get; set; } = new NdmElement(Guid.NewGuid());
public ICrossSection? CrossSection { get; set; }
public IVisualProperty VisualProperty { get; } = new VisualProperty { Opacity = 0.8d };
public IVisualProperty VisualProperty { get; set; } = new VisualProperty { Opacity = 0.8d };
public double RotationAngle { get; set; }
public IDivisionSize DivisionSize { get; } = new DivisionSize(Guid.NewGuid());
public IDivisionSize DivisionSize { get; set; } = new DivisionSize(Guid.NewGuid());
public ShapeNdmPrimitive(Guid id)
{
Id = id;
@@ -38,7 +38,9 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
public IEnumerable<INdm> GetNdms(ITriangulationOptions triangulationOptions)
{
throw new NotImplementedException();
var triangulationLogicOption = new LinePolygonTriangulationLogicOption(this, triangulationOptions);
var logic = new LinePolygonTriangulationLogic(triangulationLogicOption);
return logic.GetNdmCollection();
}
public List<INamedAreaPoint> GetValuePoints()
@@ -74,7 +76,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives
{
if (shape is ILinePolygonShape polygon)
{
var newShape = PolygonGeometryUtils.GetTratsfromedPolygon(polygon, Center.X, Center.Y);
var newShape = PolygonGeometryUtils.GetTransfromedPolygon(polygon, Center.X, Center.Y);
var calculator = new PolygonCalculator();
return calculator.ContainsPoint(newShape, point);
}

View File

@@ -23,13 +23,13 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
{
double diameter = options.Circle.Diameter;
double ndmMaxSize = options.NdmMaxSize;
int ndmMinDivision = options.NdmMinDivision;
double ndmMaxSize = options.DivisionSize.NdmMaxSize;
int ndmMinDivision = options.DivisionSize.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 = options.HeadMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm)
Material = options.HeadMaterial.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm)
});
TriangulationService.CommonTransform(ndmCollection, options);
TriangulationService.SetPrestrain(ndmCollection, options.Prestrain);

View File

@@ -18,22 +18,19 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
public IPoint2D Center { get; set; }
public double NdmMaxSize { get; }
public int NdmMinDivision { get; }
public StrainTuple Prestrain { get; set; }
public ITriangulationOptions triangulationOptions { get; set; }
public ITriangulationOptions TriangulationOptions { get; set; }
public IHeadMaterial HeadMaterial { get; set; }
public double RotationAngle { get; set; }
public IDivisionSize DivisionSize { get; }
public CircleTriangulationLogicOptions(IEllipseNdmPrimitive primitive)
{
Center = primitive.Center.Clone() as Point2D;
//to do change to ellipse
Circle = new CircleShape() { Diameter = primitive.Width };
NdmMaxSize = primitive.DivisionSize.NdmMaxSize;
NdmMinDivision = primitive.DivisionSize.NdmMinDivision;
DivisionSize = primitive.DivisionSize;
HeadMaterial = primitive.NdmElement.HeadMaterial;
Prestrain = ForceTupleService.SumTuples(primitive.NdmElement.UsersPrestrain, primitive.NdmElement.AutoPrestrain) as StrainTuple;
}

View File

@@ -1,5 +1,6 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -11,16 +12,8 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
public interface IShapeTriangulationLogicOptions : ITriangulationLogicOptions, IHasCenter2D
{
/// <summary>
/// Center of shape
/// Parameters of division
/// </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; }
IDivisionSize DivisionSize { get; }
}
}

View File

@@ -1,12 +1,21 @@
using System.Collections.Generic;
using LoaderCalculator.Data.Ndms;
using LoaderCalculator.Data.Materials;
using LoaderCalculator.Data.Ndms;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
/// <summary>
/// Implements logic of obtaining of collection of ndm parts
/// </summary>
public interface ITriangulationLogic
{
/// <summary>
/// Returns collection of ndm parts
/// </summary>
/// <returns></returns>
IEnumerable<INdm> GetNdmCollection();
/// <summary>
/// Check options of triangulation
/// </summary>
/// <param name="options"></param>
void ValidateOptions(ITriangulationLogicOptions options);
}
}

View File

@@ -6,7 +6,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public interface ITriangulationLogicOptions
{
ITriangulationOptions triangulationOptions { get; set; }
ITriangulationOptions TriangulationOptions { get; set; }
StrainTuple Prestrain { get; set; }
IHeadMaterial HeadMaterial { get; set; }
}

View File

@@ -0,0 +1,85 @@
using LoaderCalculator.Data.Materials;
using LoaderCalculator.Data.Ndms;
using LoaderCalculator.Infrastructure.Geometry;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Shapes;
using TriangleNet.Geometry;
using TriangleNet.Meshing;
using static System.Windows.Forms.Design.AxImporter;
namespace StructureHelperLogics.NdmCalculations.Triangulations
{
/// <summary>
/// Logic for triangulation of line poligon shapr into collection of ndm parts
/// </summary>
public class LinePolygonTriangulationLogic : ITriangulationLogic
{
private LinePolygonTriangulationLogicOption options;
public LinePolygonTriangulationLogic(LinePolygonTriangulationLogicOption triangulationLogicOption)
{
this.options = triangulationLogicOption;
}
/// <inheritdoc/>
public IEnumerable<INdm> GetNdmCollection()
{
IMesh mesh = GetMesh();
var material = options.HeadMaterial.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm);
List<INdm> ndms = GetNdmsByMesh(mesh, material);
return ndms;
}
private List<INdm> GetNdmsByMesh(IMesh mesh, IMaterial material)
{
List<INdm> ndmCollection = [];
foreach (var triangle in mesh.Triangles)
{
List<IPointLd2D> points = [];
for (int i = 0; i < 3; i++)
{
var vertex1 = triangle.GetVertex(i);
points.Add(new PointLd2D() { X = vertex1.X, Y = vertex1.Y });
}
var ndm = new TriangleNdm() { Point1 = points[0], Point2 = points[1], Point3 = points[2] };
ndm.Material = material;
var ndm2 = new RectangleNdm() { Width = Math.Sqrt(ndm.Area), Height = Math.Sqrt(ndm.Area), CenterX = ndm.CenterX, CenterY = ndm.CenterY, Material = ndm.Material};
ndmCollection.Add(ndm);
}
TriangulationService.SetPrestrain(ndmCollection, options.Prestrain);
return ndmCollection;
}
private IMesh GetMesh()
{
if (options.Shape is not ILinePolygonShape polygonShape)
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(options.Shape) + ": Shape is not line polygon shape");
}
var polygon = new Polygon();
List<IVertex> vertices = polygonShape.Vertices.ToList();
var contour = new List<TriangleNet.Geometry.Vertex>();
foreach (var vertex in vertices)
{
contour.Add(new TriangleNet.Geometry.Vertex(vertex.Point.X, vertex.Point.Y));
}
// Add contour to polygon — this automatically defines the connecting segments
polygon.Add(new Contour(contour));
var quality = new QualityOptions()
{
MinimumAngle = 25.0,
MaximumArea = options.DivisionSize.NdmMaxSize * options.DivisionSize.NdmMaxSize,
};
var mesh = polygon.Triangulate(quality);
return mesh;
}
/// <inheritdoc/>
public void ValidateOptions(ITriangulationLogicOptions options)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,35 @@
using StructureHelper.Models.Materials;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.Forces;
using StructureHelperLogics.Models.Primitives;
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 LinePolygonTriangulationLogicOption : IShapeTriangulationLogicOptions
{
public IPoint2D Center { get; set; }
public IDivisionSize DivisionSize { get; set; }
public ITriangulationOptions TriangulationOptions { get; set; }
public StrainTuple Prestrain { get; set; }
public IHeadMaterial HeadMaterial { get; set; }
public double RotationAngle { get; set; } = 0;
public IShape Shape { get; set; }
public LinePolygonTriangulationLogicOption(IShapeNdmPrimitive primitive, ITriangulationOptions triangulationOptions)
{
Center = primitive.Center;
DivisionSize = primitive.DivisionSize;
TriangulationOptions = triangulationOptions;
Shape = primitive.Shape;
HeadMaterial = primitive.NdmElement.HeadMaterial;
Prestrain = ForceTupleService.SumTuples(primitive.NdmElement.UsersPrestrain, primitive.NdmElement.AutoPrestrain) as StrainTuple;
}
}
}

View File

@@ -22,7 +22,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
CenterX = options.Center.X,
CenterY = options.Center.Y,
Area = options.Area,
Material = options.HeadMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm)
Material = options.HeadMaterial.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm)
};
List<INdm> ndmCollection = new () { ndm};
NdmTransform.SetPrestrain(ndmCollection, TupleConverter.ConvertToLoaderStrainMatrix(options.Prestrain));

View File

@@ -12,7 +12,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
/// </summary>
public class PointTriangulationLogicOptions : ITriangulationLogicOptions
{
public ITriangulationOptions triangulationOptions { get; set; }
public ITriangulationOptions TriangulationOptions { get; set; }
/// <summary>
///
/// </summary>

View File

@@ -44,7 +44,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
CenterX = options.Center.X,
CenterY = options.Center.Y,
Area = options.Area,
Material = options.HeadMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm)
Material = options.HeadMaterial.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm)
};
;
NdmTransform.SetPrestrain(rebarNdm, TupleConverter.ConvertToLoaderStrainMatrix(options.Prestrain));
@@ -58,7 +58,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
var material = hostPrimitive
.NdmElement
.HeadMaterial
.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm);
.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm);
var prestrain = ForceTupleService.SumTuples(hostPrimitive.NdmElement.UsersPrestrain,
hostPrimitive.NdmElement.AutoPrestrain)

View File

@@ -13,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
{
public class RebarTriangulationLogicOptions : ITriangulationLogicOptions
{
public ITriangulationOptions triangulationOptions { get; set; }
public ITriangulationOptions TriangulationOptions { get; set; }
/// <summary>
///
/// </summary>

View File

@@ -16,13 +16,13 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
{
double width = options.Rectangle.Width;
double height = options.Rectangle.Height;
double ndmMaxSize = options.NdmMaxSize;
int ndmMinDivision = options.NdmMinDivision;
double ndmMaxSize = options.DivisionSize.NdmMaxSize;
int ndmMinDivision = options.DivisionSize.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 = options.HeadMaterial.GetLoaderMaterial(options.triangulationOptions.LimiteState, options.triangulationOptions.CalcTerm)
Material = options.HeadMaterial.GetLoaderMaterial(options.TriangulationOptions.LimiteState, options.TriangulationOptions.CalcTerm)
});
TriangulationService.CommonTransform(ndmCollection, options);
double angle = options.RotationAngle;

View File

@@ -16,21 +16,20 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
public double RotationAngle { get; set; } = 0d;
/// <inheritdoc />
public IRectangleShape Rectangle { get; }
/// <inheritdoc />
public double NdmMaxSize { get; }
/// <inheritdoc />
public int NdmMinDivision { get; }
/// <inheritdoc />
public StrainTuple Prestrain { get; set; }
public ITriangulationOptions triangulationOptions { get; set; }
public ITriangulationOptions TriangulationOptions { get; set; }
public IHeadMaterial HeadMaterial { get; set; }
public IDivisionSize DivisionSize { get; } = new DivisionSize(Guid.Empty);
public RectangleTriangulationLogicOptions(IPoint2D center, IRectangleShape rectangle, double ndmMaxSize, int ndmMinDivision)
{
Center = center;
Rectangle = rectangle;
NdmMaxSize = ndmMaxSize;
NdmMinDivision = ndmMinDivision;
DivisionSize.NdmMaxSize = ndmMaxSize;
DivisionSize.NdmMinDivision = ndmMinDivision;
Prestrain = new StrainTuple();
}
@@ -39,8 +38,8 @@ namespace StructureHelperLogics.NdmCalculations.Triangulations
Center = new Point2D() {X = primitive.Center.X, Y = primitive.Center.Y };
RotationAngle = primitive.RotationAngle;
Rectangle = primitive;
NdmMaxSize = primitive.DivisionSize.NdmMaxSize;
NdmMinDivision = primitive.DivisionSize.NdmMinDivision;
DivisionSize.NdmMaxSize = primitive.DivisionSize.NdmMaxSize;
DivisionSize.NdmMinDivision = primitive.DivisionSize.NdmMinDivision;
HeadMaterial = primitive.NdmElement.HeadMaterial;
Prestrain = ForceTupleService.SumTuples(primitive.NdmElement.UsersPrestrain, primitive.NdmElement.AutoPrestrain) as StrainTuple;
}