private PathControlPoint addControlPoint(Vector2 position) { position -= HitObject.Position; int insertionIndex = 0; float minDistance = float.MaxValue; for (int i = 0; i < controlPoints.Count - 1; i++) { float dist = new Line(controlPoints[i].Position, controlPoints[i + 1].Position).DistanceToPoint(position); if (dist < minDistance) { insertionIndex = i + 1; minDistance = dist; } } var pathControlPoint = new PathControlPoint { Position = position }; // Move the control points from the insertion index onwards to make room for the insertion controlPoints.Insert(insertionIndex, pathControlPoint); HitObject.SnapTo(snapProvider); return(pathControlPoint); }
private void removeControlPoints(List <PathControlPoint> toRemove) { // Ensure that there are any points to be deleted if (toRemove.Count == 0) { return; } foreach (var c in toRemove) { // The first control point in the slider must have a type, so take it from the previous "first" one // Todo: Should be handled within SliderPath itself if (c == controlPoints[0] && controlPoints.Count > 1 && controlPoints[1].Type == null) { controlPoints[1].Type = controlPoints[0].Type; } controlPoints.Remove(c); } // Snap the slider to the current beat divisor before checking length validity. HitObject.SnapTo(snapProvider); // If there are 0 or 1 remaining control points, or the slider has an invalid length, it is in a degenerate form and should be deleted if (controlPoints.Count <= 1 || !HitObject.Path.HasValidLength) { placementHandler?.Delete(HitObject); return; } // The path will have a non-zero offset if the head is removed, but sliders don't support this behaviour since the head is positioned at the slider's position // So the slider needs to be offset by this amount instead, and all control points offset backwards such that the path is re-positioned at (0, 0) Vector2 first = controlPoints[0].Position; foreach (var c in controlPoints) { c.Position -= first; } HitObject.Position += first; }