diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs index 77fa64b0b1..8e94112866 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs @@ -244,6 +244,7 @@ public Vector2 ClampScaleToPlayfieldBounds(Vector2 scale, Vector2? origin = null return scale; + // Clamps the scale vector s such that the point p scaled by s is within the rectangle defined by lowerBounds and upperBounds Vector2 clampToBound(Vector2 s, Vector2 p, Vector2 lowerBounds, Vector2 upperBounds) { p -= actualOrigin; @@ -286,18 +287,25 @@ Vector2 clampToBound(Vector2 s, Vector2 p, Vector2 lowerBounds, Vector2 upperBou return s; } + // Computes the bounds for the magnitude of the scaled point p with respect to the bounds lowerBounds and upperBounds (float, float) computeBounds(Vector2 lowerBounds, Vector2 upperBounds, Vector2 p) { var sLowerBounds = Vector2.Divide(lowerBounds, p); var sUpperBounds = Vector2.Divide(upperBounds, p); + + // If the point is negative, then the bounds are flipped if (p.X < 0) (sLowerBounds.X, sUpperBounds.X) = (sUpperBounds.X, sLowerBounds.X); if (p.Y < 0) (sLowerBounds.Y, sUpperBounds.Y) = (sUpperBounds.Y, sLowerBounds.Y); + + // If the point is at zero, then any scale will have no effect on the point so the bounds are infinite + // The float division would already give us infinity for the bounds, but the sign is not consistent so we have to manually set it if (Precision.AlmostEquals(p.X, 0)) (sLowerBounds.X, sUpperBounds.X) = (float.NegativeInfinity, float.PositiveInfinity); if (Precision.AlmostEquals(p.Y, 0)) (sLowerBounds.Y, sUpperBounds.Y) = (float.NegativeInfinity, float.PositiveInfinity); + return (MathF.Max(sLowerBounds.X, sLowerBounds.Y), MathF.Min(sUpperBounds.X, sUpperBounds.Y)); } }