From c31e56869cfd616f3b939163d134016d5b155862 Mon Sep 17 00:00:00 2001 From: Evgeny Redikultsev Date: Sun, 7 Sep 2025 08:12:07 +0500 Subject: [PATCH] Add polygon shape --- StructureHelper/StructureHelper.csproj | 2 +- .../Models/Shapes/IPolygonShape.cs | 23 ++++++ .../Models/Shapes/IVertex.cs | 15 ++++ .../Shapes/Logics/IPolygonCalculator.cs | 17 ++++ .../Models/Shapes/Logics/PolygonCalculator.cs | 77 ++++++++++++++++++ .../Shapes/Logics/PolygonGeometryUtils.cs | 73 +++++++++++++++++ .../Shapes/Logics/PolygonUpdateStrategy.cs | 48 +++++++++++ .../Models/Shapes/PolygonShape.cs | 71 ++++++++++++++++ StructureHelperCommon/Models/Shapes/Vertex.cs | 19 +++++ .../StructureHelperCommon.csproj | 2 +- .../Primitives/DivisionSize.cs | 5 -- .../Primitives/EllipseNdmPrimitive.cs | 2 +- .../Primitives/INamedAreaPoint.cs | 2 +- .../Primitives/IShapeNDMPrimitive.cs | 14 ++++ .../Primitives/Logics/MeshNDMLogic.cs | 15 ++++ .../Logics/ShapeNDMPrimitiveUpdateStrategy.cs | 47 +++++++++++ .../Primitives/NamedAreaPoint.cs | 2 +- .../Primitives/RectangleNdmPrimitive.cs | 2 +- .../Primitives/ShapeNdmPrimitive.cs | 80 +++++++++++++++++++ .../StructureHelperTests.csproj | 8 +- 20 files changed, 509 insertions(+), 15 deletions(-) create mode 100644 StructureHelperCommon/Models/Shapes/IPolygonShape.cs create mode 100644 StructureHelperCommon/Models/Shapes/IVertex.cs create mode 100644 StructureHelperCommon/Models/Shapes/Logics/IPolygonCalculator.cs create mode 100644 StructureHelperCommon/Models/Shapes/Logics/PolygonCalculator.cs create mode 100644 StructureHelperCommon/Models/Shapes/Logics/PolygonGeometryUtils.cs create mode 100644 StructureHelperCommon/Models/Shapes/Logics/PolygonUpdateStrategy.cs create mode 100644 StructureHelperCommon/Models/Shapes/PolygonShape.cs create mode 100644 StructureHelperCommon/Models/Shapes/Vertex.cs create mode 100644 StructureHelperLogics/NdmCalculations/Primitives/IShapeNDMPrimitive.cs create mode 100644 StructureHelperLogics/NdmCalculations/Primitives/Logics/MeshNDMLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Primitives/Logics/ShapeNDMPrimitiveUpdateStrategy.cs create mode 100644 StructureHelperLogics/NdmCalculations/Primitives/ShapeNdmPrimitive.cs diff --git a/StructureHelper/StructureHelper.csproj b/StructureHelper/StructureHelper.csproj index 684d0cc..4726725 100644 --- a/StructureHelper/StructureHelper.csproj +++ b/StructureHelper/StructureHelper.csproj @@ -61,7 +61,7 @@ - + diff --git a/StructureHelperCommon/Models/Shapes/IPolygonShape.cs b/StructureHelperCommon/Models/Shapes/IPolygonShape.cs new file mode 100644 index 0000000..a772ed9 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/IPolygonShape.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Shapes +{ + public interface IPolygonShape : IShape + { + IReadOnlyList Vertices { get; } + bool IsClosed { get; set; } + + IVertex AddVertex(IVertex vertex); + IVertex InsertVertex(int index, IVertex vertex); + IVertex AddVertexBefore(IVertex existing, IVertex vertex); + IVertex AddVertexAfter(IVertex existing, IVertex vertex); + + void RemoveVertex(IVertex vertex); + void Clear(); + } + +} diff --git a/StructureHelperCommon/Models/Shapes/IVertex.cs b/StructureHelperCommon/Models/Shapes/IVertex.cs new file mode 100644 index 0000000..00f06b8 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/IVertex.cs @@ -0,0 +1,15 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Shapes +{ + public interface IVertex : ISaveable + { + IPoint2D Point { get; set; } + } + +} diff --git a/StructureHelperCommon/Models/Shapes/Logics/IPolygonCalculator.cs b/StructureHelperCommon/Models/Shapes/Logics/IPolygonCalculator.cs new file mode 100644 index 0000000..eda4dc0 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/Logics/IPolygonCalculator.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Shapes; + +namespace StructureHelperCommon.Models.Shapes +{ + public interface IPolygonCalculator + { + double GetPerimeter(IPolygonShape polygon); + double GetArea(IPolygonShape polygon); + bool ContainsPoint(IPolygonShape polygon, IPoint2D point); + } + +} diff --git a/StructureHelperCommon/Models/Shapes/Logics/PolygonCalculator.cs b/StructureHelperCommon/Models/Shapes/Logics/PolygonCalculator.cs new file mode 100644 index 0000000..c229119 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/Logics/PolygonCalculator.cs @@ -0,0 +1,77 @@ +using System; + +namespace StructureHelperCommon.Models.Shapes +{ + public class PolygonCalculator : IPolygonCalculator + { + public double GetPerimeter(IPolygonShape polygon) + { + if (polygon.Vertices.Count < 2) + return 0; + + double perimeter = 0; + + for (int i = 0; i < polygon.Vertices.Count - 1; i++) + { + perimeter += Distance(polygon.Vertices[i].Point, polygon.Vertices[i + 1].Point); + } + + if (polygon.IsClosed && polygon.Vertices.Count > 2) + { + perimeter += Distance(polygon.Vertices[^1].Point, polygon.Vertices[0].Point); + } + + return perimeter; + } + + public double GetArea(IPolygonShape polygon) + { + if (!polygon.IsClosed || polygon.Vertices.Count < 3) + return 0; + + // Shoelace formula + double sum = 0; + for (int i = 0; i < polygon.Vertices.Count; i++) + { + var p1 = polygon.Vertices[i].Point; + var p2 = polygon.Vertices[(i + 1) % polygon.Vertices.Count].Point; + sum += (p1.X * p2.Y - p2.X * p1.Y); + } + + return Math.Abs(sum) / 2.0; + } + + public bool ContainsPoint(IPolygonShape polygon, IPoint2D point) + { + if (!polygon.IsClosed || polygon.Vertices.Count < 3) + return false; + + // Ray casting algorithm + bool inside = false; + int j = polygon.Vertices.Count - 1; + + for (int i = 0; i < polygon.Vertices.Count; i++) + { + var pi = polygon.Vertices[i].Point; + var pj = polygon.Vertices[j].Point; + + if (((pi.Y > point.Y) != (pj.Y > point.Y)) && + (point.X < (pj.X - pi.X) * (point.Y - pi.Y) / (pj.Y - pi.Y) + pi.X)) + { + inside = !inside; + } + j = i; + } + + return inside; + } + + private double Distance(IPoint2D p1, IPoint2D p2) + { + double dx = p2.X - p1.X; + double dy = p2.Y - p1.Y; + return Math.Sqrt(dx * dx + dy * dy); + } + } + +} diff --git a/StructureHelperCommon/Models/Shapes/Logics/PolygonGeometryUtils.cs b/StructureHelperCommon/Models/Shapes/Logics/PolygonGeometryUtils.cs new file mode 100644 index 0000000..08de6f5 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/Logics/PolygonGeometryUtils.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Shapes; + +namespace StructureHelperCommon.Models.Shapes +{ + public static class PolygonGeometryUtils + { + public static bool DoPolygonsEdgesIntersect(IPolygonShape polygon) + { + var vertices = polygon.Vertices; + int n = vertices.Count; + + if (n < 4) + return false; // Triangles cannot self-intersect + + for (int i = 0; i < n; i++) + { + var a1 = vertices[i].Point; + var a2 = vertices[(i + 1) % n].Point; + + for (int j = i + 1; j < n; j++) + { + var b1 = vertices[j].Point; + var b2 = vertices[(j + 1) % n].Point; + + // Skip adjacent edges (they share a vertex) + if (AreAdjacent(i, j, n, polygon.IsClosed)) + continue; + + if (SegmentsIntersect(a1, a2, b1, b2)) + return true; + } + } + + return false; + } + + private static bool AreAdjacent(int i, int j, int n, bool isClosed) + { + // Edges (i,i+1) and (j,j+1) are adjacent if: + if (j == i) return true; + if (j == i + 1) return true; + if (i == j + 1) return true; + + // Special case: first and last edges in closed polygon + if (isClosed && + ((i == 0 && j == n - 1) || (j == 0 && i == n - 1))) + return true; + + return false; + } + + private static bool SegmentsIntersect(IPoint2D p1, IPoint2D p2, IPoint2D q1, IPoint2D q2) + { + return (Orientation(p1, p2, q1) * Orientation(p1, p2, q2) < 0) && + (Orientation(q1, q2, p1) * Orientation(q1, q2, p2) < 0); + } + + private static int Orientation(IPoint2D a, IPoint2D b, IPoint2D c) + { + double val = (b.Y - a.Y) * (c.X - b.X) - + (b.X - a.X) * (c.Y - b.Y); + + if (Math.Abs(val) < 1e-12) return 0; // Collinear + return (val > 0) ? 1 : -1; // Clockwise / Counter-clockwise + } + } + +} diff --git a/StructureHelperCommon/Models/Shapes/Logics/PolygonUpdateStrategy.cs b/StructureHelperCommon/Models/Shapes/Logics/PolygonUpdateStrategy.cs new file mode 100644 index 0000000..11d7e86 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/Logics/PolygonUpdateStrategy.cs @@ -0,0 +1,48 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Shapes; + +namespace StructureHelperCommon.Models.Shapes +{ + public class PolygonUpdateStrategy : IUpdateStrategy + { + public void Update(IPolygonShape targetObject, IPolygonShape sourceObject) + { + CheckObject.IsNull(sourceObject); + CheckObject.IsNull(targetObject); + if (ReferenceEquals(targetObject, sourceObject)) { return; } + + // Update simple properties + targetObject.IsClosed = sourceObject.IsClosed; + + // Replace vertices + targetObject.Clear(); + foreach (var vertex in sourceObject.Vertices) + { + // Copy the underlying point into a new vertex + Vertex newVertex = GetVertexClone(vertex); + targetObject.AddVertex(newVertex); + } + } + + private static Vertex GetVertexClone(IVertex vertex) + { + Point2D newVertexPoint = new(Guid.NewGuid()) + { + X = vertex.Point.X, + Y = vertex.Point.Y + }; + Vertex newVertex = new(Guid.NewGuid()) + { + Point = newVertexPoint + }; + return newVertex; + } + } + +} diff --git a/StructureHelperCommon/Models/Shapes/PolygonShape.cs b/StructureHelperCommon/Models/Shapes/PolygonShape.cs new file mode 100644 index 0000000..fb17e27 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/PolygonShape.cs @@ -0,0 +1,71 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; + +namespace StructureHelperCommon.Models.Shapes +{ + public class PolygonShape : IPolygonShape + { + private readonly List _vertices = new(); + + public Guid Id { get; } + public IReadOnlyList Vertices => _vertices; + public bool IsClosed { get; set; } + + public PolygonShape(Guid id) + { + Id = id; + } + + public IVertex AddVertex(IVertex vertex) + { + _vertices.Add(vertex); + return vertex; + } + + public IVertex InsertVertex(int index, IVertex vertex) + { + _vertices.Insert(index, vertex); + return vertex; + } + + public IVertex AddVertexBefore(IVertex existing, IVertex vertex) + { + int index = CheckVertexExists(existing); + _vertices.Insert(index, vertex); + return vertex; + } + public IVertex AddVertexAfter(IVertex existing, IVertex vertex) + { + int index = CheckVertexExists(existing); + _vertices.Insert(index + 1, vertex); + return vertex; + } + + public void RemoveVertex(IVertex vertex) + { + if (!_vertices.Remove(vertex)) + throw new InvalidOperationException("The specified vertex was not found in the polygon."); + } + + public void Clear() + { + _vertices.Clear(); + } + + + + private int CheckVertexExists(IVertex existing) + { + int index = _vertices.IndexOf(existing); + if (index == -1) + { + throw new StructureHelperException("The specified vertex was not found in the polygon."); + } + + return index; + } + + } + +} diff --git a/StructureHelperCommon/Models/Shapes/Vertex.cs b/StructureHelperCommon/Models/Shapes/Vertex.cs new file mode 100644 index 0000000..15620e4 --- /dev/null +++ b/StructureHelperCommon/Models/Shapes/Vertex.cs @@ -0,0 +1,19 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; + +namespace StructureHelperCommon.Models.Shapes +{ + public class Vertex : IVertex + { + public Guid Id { get; } + + public Vertex(Guid id) + { + Id = id; + } + + public IPoint2D Point { get; set; } + + } + +} diff --git a/StructureHelperCommon/StructureHelperCommon.csproj b/StructureHelperCommon/StructureHelperCommon.csproj index 233784a..c837296 100644 --- a/StructureHelperCommon/StructureHelperCommon.csproj +++ b/StructureHelperCommon/StructureHelperCommon.csproj @@ -11,7 +11,7 @@ - + diff --git a/StructureHelperLogics/NdmCalculations/Primitives/DivisionSize.cs b/StructureHelperLogics/NdmCalculations/Primitives/DivisionSize.cs index dc1b408..6ee5383 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/DivisionSize.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/DivisionSize.cs @@ -21,10 +21,5 @@ namespace StructureHelperLogics.NdmCalculations.Primitives { Id = id; } - - public DivisionSize() : this (Guid.NewGuid()) - { - - } } } diff --git a/StructureHelperLogics/NdmCalculations/Primitives/EllipseNdmPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/EllipseNdmPrimitive.cs index f85cac5..4309574 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/EllipseNdmPrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/EllipseNdmPrimitive.cs @@ -42,7 +42,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives /// public INdmElement NdmElement { get; } = new NdmElement(); /// - public IDivisionSize DivisionSize { get; } = new DivisionSize(); + public IDivisionSize DivisionSize { get; } = new DivisionSize(Guid.NewGuid()); /// public IShape Shape => rectangleShape; /// diff --git a/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs b/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs index c6bc330..c5974b6 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/INamedAreaPoint.cs @@ -6,6 +6,6 @@ namespace StructureHelperLogics.NdmCalculations.Primitives { double Area { get; set; } string Name { get; set; } - Point2D Point { get; set; } + IPoint2D Point { get; set; } } } \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Primitives/IShapeNDMPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/IShapeNDMPrimitive.cs new file mode 100644 index 0000000..2c84f43 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/IShapeNDMPrimitive.cs @@ -0,0 +1,14 @@ +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 IShapeNDMPrimitive : INdmPrimitive, IHasDivisionSize + { + void SetShape(IShape shape); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Primitives/Logics/MeshNDMLogic.cs b/StructureHelperLogics/NdmCalculations/Primitives/Logics/MeshNDMLogic.cs new file mode 100644 index 0000000..2564e27 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/Logics/MeshNDMLogic.cs @@ -0,0 +1,15 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Primitives +{ + public interface MeshNDMLogic + { + IEnumerable GetNdms(ITriangulationOptions triangulation); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Primitives/Logics/ShapeNDMPrimitiveUpdateStrategy.cs b/StructureHelperLogics/NdmCalculations/Primitives/Logics/ShapeNDMPrimitiveUpdateStrategy.cs new file mode 100644 index 0000000..fe8c50b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/Logics/ShapeNDMPrimitiveUpdateStrategy.cs @@ -0,0 +1,47 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Shapes; +using StructureHelperCommon.Models.Shapes.Logics; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Primitives +{ + public class ShapeNDMPrimitiveUpdateStrategy : IUpdateStrategy + { + private IUpdateStrategy basePrimitiveUpdateStrategy; + private IUpdateStrategy divisionPropsUpdateStrategy; + private IUpdateStrategy shapeUpdateStrategy; + + public ShapeNDMPrimitiveUpdateStrategy( + IUpdateStrategy basePrimitiveUpdateStrategy, + IUpdateStrategy divisionPropsUpdateStrategy, + IUpdateStrategy shapeUpdateStrategy) + { + this.basePrimitiveUpdateStrategy = basePrimitiveUpdateStrategy; + this.divisionPropsUpdateStrategy = divisionPropsUpdateStrategy; + this.shapeUpdateStrategy = shapeUpdateStrategy; + } + + public void Update(IShapeNDMPrimitive targetObject, IShapeNDMPrimitive sourceObject) + { + CheckObject.IsNull(sourceObject, "source object"); + CheckObject.IsNull(targetObject, "target object"); + if (ReferenceEquals(targetObject, sourceObject)) { return; } + InitializeStrategies(); + basePrimitiveUpdateStrategy.Update(targetObject, sourceObject); + divisionPropsUpdateStrategy.Update(targetObject.DivisionSize, sourceObject.DivisionSize); + shapeUpdateStrategy.Update(targetObject.Shape, sourceObject.Shape); + } + + private void InitializeStrategies() + { + basePrimitiveUpdateStrategy ??= new BaseUpdateStrategy(); + divisionPropsUpdateStrategy ??= new DivisionSizeUpdateStrategy(); + shapeUpdateStrategy ??= new ShapeUpdateStrategy(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs b/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs index 1f4b2f5..318b0b6 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/NamedAreaPoint.cs @@ -11,7 +11,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives public class NamedAreaPoint : INamedAreaPoint { public string Name { get; set; } - public Point2D Point { get; set; } + public IPoint2D Point { get; set; } public double Area { get; set; } } } diff --git a/StructureHelperLogics/NdmCalculations/Primitives/RectangleNdmPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/RectangleNdmPrimitive.cs index 11092b3..2406cf9 100644 --- a/StructureHelperLogics/NdmCalculations/Primitives/RectangleNdmPrimitive.cs +++ b/StructureHelperLogics/NdmCalculations/Primitives/RectangleNdmPrimitive.cs @@ -24,7 +24,7 @@ namespace StructureHelperLogics.NdmCalculations.Primitives public INdmElement NdmElement { get; } = new NdmElement(); - public IDivisionSize DivisionSize { get; } = new DivisionSize(); + public IDivisionSize DivisionSize { get; } = new DivisionSize(Guid.NewGuid()); public IShape Shape => rectangleShape; diff --git a/StructureHelperLogics/NdmCalculations/Primitives/ShapeNdmPrimitive.cs b/StructureHelperLogics/NdmCalculations/Primitives/ShapeNdmPrimitive.cs new file mode 100644 index 0000000..537cd8a --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Primitives/ShapeNdmPrimitive.cs @@ -0,0 +1,80 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.CrossSections; +using StructureHelperLogics.NdmCalculations.Triangulations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Primitives +{ + public class ShapeNdmPrimitive : IShapeNDMPrimitive + { + private IShape shape; + + public Guid Id { get; } + 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 ICrossSection? CrossSection { get; set; } + public IVisualProperty VisualProperty { get; } = new VisualProperty { Opacity = 0.8d }; + public double RotationAngle { get; set; } + public IDivisionSize DivisionSize { get; } = new DivisionSize(Guid.NewGuid()); + public ShapeNdmPrimitive(Guid id) + { + Id = id; + } + + public object Clone() + { + throw new NotImplementedException(); + } + + public IEnumerable GetNdms(ITriangulationOptions triangulationOptions) + { + throw new NotImplementedException(); + } + + public List GetValuePoints() + { + var points = new List(); + INamedAreaPoint newPoint; + newPoint = new NamedAreaPoint + { + Name = "Center", + Point = Center.Clone() as Point2D, + Area = 0d + }; + points.Add(newPoint); + if (shape is IPolygonShape polygon) + { + int i = 0; + foreach (var item in polygon.Vertices) + { + newPoint = new NamedAreaPoint + { + Name = $"Vertex {i}", + Point = item.Point.Clone() as IPoint2D, + Area = 0d + }; + points.Add(newPoint); + i++; + } + } + return points; + } + + public bool IsPointInside(IPoint2D point) + { + throw new NotImplementedException(); + } + + public void SetShape(IShape shape) + { + this.shape = shape; + } + } +} diff --git a/StructureHelperTests/StructureHelperTests.csproj b/StructureHelperTests/StructureHelperTests.csproj index 5db161e..4995b4c 100644 --- a/StructureHelperTests/StructureHelperTests.csproj +++ b/StructureHelperTests/StructureHelperTests.csproj @@ -9,11 +9,11 @@ - - + + - - + +