mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 14:37:30 +08:00
fix scale clamp computation and code cleanup
This commit is contained in:
parent
0677430975
commit
08e1698bb6
@ -240,48 +240,66 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
points = originalConvexHull!;
|
||||
|
||||
foreach (var point in points)
|
||||
{
|
||||
scale = clampToBound(scale, point, Vector2.Zero, OsuPlayfield.BASE_SIZE);
|
||||
}
|
||||
|
||||
return Vector2.ComponentMax(scale, new Vector2(Precision.FLOAT_EPSILON));
|
||||
return scale;
|
||||
|
||||
float minComponent(Vector2 v) => MathF.Min(v.X, v.Y);
|
||||
float maxComponent(Vector2 v) => MathF.Max(v.X, v.Y);
|
||||
|
||||
Vector2 clampToBound(Vector2 s, Vector2 p, Vector2 lowerBound, Vector2 upperBound)
|
||||
Vector2 clampToBound(Vector2 s, Vector2 p, Vector2 lowerBounds, Vector2 upperBounds)
|
||||
{
|
||||
p -= actualOrigin;
|
||||
lowerBound -= actualOrigin;
|
||||
upperBound -= actualOrigin;
|
||||
lowerBounds -= actualOrigin;
|
||||
upperBounds -= actualOrigin;
|
||||
// a.X is the rotated X component of p with respect to the X bounds
|
||||
// a.Y is the rotated X component of p with respect to the Y bounds
|
||||
// b.X is the rotated Y component of p with respect to the X bounds
|
||||
// b.Y is the rotated Y component of p with respect to the Y bounds
|
||||
var a = new Vector2(cos * cos * p.X - sin * cos * p.Y, -sin * cos * p.X + sin * sin * p.Y);
|
||||
var b = new Vector2(sin * sin * p.X + sin * cos * p.Y, sin * cos * p.X + cos * cos * p.Y);
|
||||
|
||||
float sLowerBound, sUpperBound;
|
||||
|
||||
switch (adjustAxis)
|
||||
{
|
||||
case Axes.X:
|
||||
var lowerBounds = Vector2.Divide(lowerBound - b, a);
|
||||
var upperBounds = Vector2.Divide(upperBound - b, a);
|
||||
if (a.X < 0)
|
||||
(lowerBounds, upperBounds) = (upperBounds, lowerBounds);
|
||||
s.X = MathHelper.Clamp(s.X, maxComponent(lowerBounds), minComponent(upperBounds));
|
||||
(sLowerBound, sUpperBound) = computeBounds(lowerBounds - b, upperBounds - b, a);
|
||||
s.X = MathHelper.Clamp(s.X, sLowerBound, sUpperBound);
|
||||
break;
|
||||
|
||||
case Axes.Y:
|
||||
var lowerBoundsY = Vector2.Divide(lowerBound - a, b);
|
||||
var upperBoundsY = Vector2.Divide(upperBound - a, b);
|
||||
if (b.Y < 0)
|
||||
(lowerBoundsY, upperBoundsY) = (upperBoundsY, lowerBoundsY);
|
||||
s.Y = MathHelper.Clamp(s.Y, maxComponent(lowerBoundsY), minComponent(upperBoundsY));
|
||||
(sLowerBound, sUpperBound) = computeBounds(lowerBounds - a, upperBounds - a, b);
|
||||
s.Y = MathHelper.Clamp(s.Y, sLowerBound, sUpperBound);
|
||||
break;
|
||||
|
||||
case Axes.Both:
|
||||
// s = Vector2.ComponentMin(s, s * minPositiveComponent(Vector2.Divide(bound, a * s.X + b * s.Y)));
|
||||
// Here we compute the bounds for the magnitude multiplier of the scale vector
|
||||
// Therefore the ratio s.X / s.Y will be maintained
|
||||
(sLowerBound, sUpperBound) = computeBounds(lowerBounds, upperBounds, a * s.X + b * s.Y);
|
||||
s.X = s.X < 0
|
||||
? MathHelper.Clamp(s.X, s.X * sUpperBound, s.X * sLowerBound)
|
||||
: MathHelper.Clamp(s.X, s.X * sLowerBound, s.X * sUpperBound);
|
||||
s.Y = s.Y < 0
|
||||
? MathHelper.Clamp(s.Y, s.Y * sUpperBound, s.Y * sLowerBound)
|
||||
: MathHelper.Clamp(s.Y, s.Y * sLowerBound, s.Y * sUpperBound);
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
(float, float) computeBounds(Vector2 lowerBounds, Vector2 upperBounds, Vector2 p)
|
||||
{
|
||||
var sLowerBounds = Vector2.Divide(lowerBounds, p);
|
||||
var sUpperBounds = Vector2.Divide(upperBounds, p);
|
||||
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 (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));
|
||||
}
|
||||
}
|
||||
|
||||
private void moveSelectionInBounds()
|
||||
|
@ -180,7 +180,9 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
if (!scaleHandler.OriginalSurroundingQuad.HasValue)
|
||||
return;
|
||||
|
||||
const float min_scale = -10;
|
||||
const float max_scale = 10;
|
||||
|
||||
var scale = scaleHandler.ClampScaleToPlayfieldBounds(new Vector2(max_scale), getOriginPosition(scaleInfo.Value), getAdjustAxis(scaleInfo.Value), getRotation(scaleInfo.Value));
|
||||
|
||||
if (!scaleInfo.Value.XAxis)
|
||||
@ -190,15 +192,14 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
|
||||
scaleInputBindable.MaxValue = MathF.Max(1, MathF.Min(scale.X, scale.Y));
|
||||
|
||||
const float min_scale = -10;
|
||||
scale = scaleHandler.ClampScaleToPlayfieldBounds(new Vector2(min_scale), getOriginPosition(scaleInfo.Value), getAdjustAxis(scaleInfo.Value), getRotation(scaleInfo.Value));
|
||||
|
||||
if (!scaleInfo.Value.XAxis)
|
||||
scale.X = max_scale;
|
||||
scale.X = min_scale;
|
||||
if (!scaleInfo.Value.YAxis)
|
||||
scale.Y = max_scale;
|
||||
scale.Y = min_scale;
|
||||
|
||||
scaleInputBindable.MinValue = MathF.Min(-1, MathF.Max(scale.X, scale.Y));
|
||||
scaleInputBindable.MinValue = MathF.Min(1, MathF.Max(scale.X, scale.Y));
|
||||
}
|
||||
|
||||
private void setOrigin(ScaleOrigin origin)
|
||||
|
Loading…
Reference in New Issue
Block a user