diff --git a/OpenNest.Core/Geometry/Shape.cs b/OpenNest.Core/Geometry/Shape.cs index 4a552a5..1123974 100644 --- a/OpenNest.Core/Geometry/Shape.cs +++ b/OpenNest.Core/Geometry/Shape.cs @@ -200,6 +200,68 @@ namespace OpenNest.Geometry return closestPt; } + /// + /// Returns a new shape with entities reordered so that the given point on + /// the given entity becomes the new start point of the contour. + /// + /// The point on the entity to reindex at. + /// The entity containing the point. + /// A new reindexed shape. + public Shape ReindexAt(Vector point, Entity entity) + { + // Circle case: return a new shape with just the circle + if (entity is Circle) + { + var result = new Shape(); + result.Entities.Add(entity); + return result; + } + + var i = Entities.IndexOf(entity); + if (i < 0) + throw new ArgumentException("Entity not found in shape", nameof(entity)); + + // Split the entity at the point + Entity firstHalf = null; + Entity secondHalf = null; + + if (entity is Line line) + { + var (f, s) = line.SplitAt(point); + firstHalf = f; + secondHalf = s; + } + else if (entity is Arc arc) + { + var (f, s) = arc.SplitAt(point); + firstHalf = f; + secondHalf = s; + } + + // Build reindexed entity list + var entities = new List(); + + // secondHalf of split entity (if not null) + if (secondHalf != null) + entities.Add(secondHalf); + + // Entities after the split index (wrapping) + for (var j = i + 1; j < Entities.Count; j++) + entities.Add(Entities[j]); + + // Entities before the split index (wrapping) + for (var j = 0; j < i; j++) + entities.Add(Entities[j]); + + // firstHalf of split entity (if not null) + if (firstHalf != null) + entities.Add(firstHalf); + + var reindexed = new Shape(); + reindexed.Entities.AddRange(entities); + return reindexed; + } + /// /// Converts the shape to a polygon. ///