Spline throws ArgumentException due to control points being too close

Hello everyone!

At the moment, I’m developing a visualization of a rope composed by tiny 2d box colliders. Due to the nature of the physics simulation of the rope, the control points are close to each other. Thus, I’ve decided to force the visualization to keep the points at a minimal safe distance in order to avoid getting an ArgumentException thrown by spline. Although, it seems that even though I assure a greater distance than the minimum established by Spline, 0.01f, the exception is thrown anyways.

private void SafeSequentialInsertPointIntoSpline(int index, Vector3 position)
        {
            if (index < _spriteShapeController.spline.GetPointCount() - 1)
            {
                throw new InvalidOperationException("Point is not being inserted sequentially.");
            }
           
            Vector3 previousPoint;
            if (index > 0)
            {
                previousPoint = _spriteShapeController.spline.GetPosition(index - 1);

                float squaredDistance = Vector3.SqrMagnitude(previousPoint - position);

                if (squaredDistance < MinimalSafeDistanceBetweenPoints * MinimalSafeDistanceBetweenPoints)
                {
                    Vector3 direction = position - previousPoint;

                    position += MinimalSafeDistanceBetweenPoints * direction.normalized;
                }
            }
           
            _spriteShapeController.spline.InsertPointAt(index, position);
        }

[Full implementation can be seen on balloondle/RopeVisualizer.cs at gameplay-mechanics · elementalg/balloondle (github.com)]

The method has been debugged, and the distance is assured to be greater than the minimum.

Any ideas on why this may happen?

Thank you for your time!

Kinds Regards,
Gabriel.

It seems the problem was caused by the spline’s point validation logic, because it also checks the distance between a point and the first point always, thus, the new implementation which seems to work, is the following one:

private void SafeSequentialInsertPointIntoSpline(int index, Vector3 position)
        {
            if (index < _spriteShapeController.spline.GetPointCount() - 1)
            {
                throw new InvalidOperationException("Point is not being inserted sequentially.");
            }
           
            if (index > 0)
            {
                Vector3 previousPoint = _spriteShapeController.spline.GetPosition(index - 1);
                // Check distance with the start of the spline, due to the position validating logic of Spline.
                Vector3 originPoint = _spriteShapeController.spline.GetPosition(0);
               
                float squaredDistanceFromPreviousPoint = Vector3.SqrMagnitude(previousPoint - position);
                float squaredDistanceFromOriginPoint = Vector3.SqrMagnitude(originPoint - position);
               
                Vector3 safeDirection = (position - originPoint).normalized + (position - previousPoint).normalized;

                if (squaredDistanceFromPreviousPoint <
                    MinimalSafeDistanceBetweenPoints * MinimalSafeDistanceBetweenPoints
                    || squaredDistanceFromOriginPoint <
                    MinimalSafeDistanceBetweenPoints * MinimalSafeDistanceBetweenPoints)
                {
                    position += MinimalSafeDistanceBetweenPoints * safeDirection.normalized;
                }
            }
           
            _spriteShapeController.spline.InsertPointAt(index, position);
        }

Thread can be closed now.