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.
///