I was trying to work it out without having to use another dreaded square root and failed. I guess there is no way of avoiding it with this scenario.
The code is now:
float radius_Bounding_Sphere = 1.5f; float radius_Tube = 2.0f; // Find the distance between the object and the nearest point on the segment // The distance can also be found with the a non normalized normal using normal.Length() float distance = (float)Math.Sqrt(debug_Segment.SquareDistanceToPoint(position_Projected)); distance += radius_Bounding_Sphere; // If the object is outside the radius (> instead of >= means I don't have to use an Epsilon) if (distance > radius_Tube) { // Compute the closest point on the segement to the projected position Vector3 center_Segment = debug_Segment.ClosestPtPointSegment(position_Projected); // Calculate the normal based on the closest point on segment to object's position Vector3 normal = center_Segment - position_Projected; normal.Normalize(); // When repositioning keep the position + bounding sphere radius inside tube radius position_Projected = center_Segment - normal * (radius_Tube - radius_Bounding_Sphere); } // Update object's position with final projected position (doesn't change if key isn't pressed) debug_Polygon[0].Position = position_Projected;