public OsuPixel PointAtDistance(double length) { switch (Order) { case 0: return(null); case 1: return(Points[0]); default: return(MathUtlity.PointAtDistance(Points, length)); } }
internal void CalcStrain(CatchDifficultyHitObject lastHitObject, double timeRate) { var time = (HitObject.Offset - lastHitObject.HitObject.Offset) / timeRate; var decay = Math.Pow(Constants.DecayBase, time / 1000d); Offset = MathUtlity.Clamp( lastHitObject.ScaledPosition + lastHitObject.Offset, ScaledPosition - (Constants.NormalizedHitobjectRadius - _errorMargin), ScaledPosition + (Constants.NormalizedHitobjectRadius - _errorMargin)) - ScaledPosition; LastMovement = Math.Abs(ScaledPosition - lastHitObject.ScaledPosition + Offset - lastHitObject.Offset); var addition = Math.Pow(LastMovement, 1.3) / 500; if (ScaledPosition < lastHitObject.ScaledPosition) { LastMovement *= -1; } var additionBonus = 0d; var sqrtTime = Math.Sqrt(Math.Max(time, 25)); if (Math.Abs(LastMovement) > 0.1) { if (Math.Abs(lastHitObject.LastMovement) > 0.1 && MathUtlity.Sign(LastMovement) != MathUtlity.Sign(lastHitObject.LastMovement)) { var bonus = Constants.DirectionChangeBonus / sqrtTime; var bonusFactor = Math.Min(_errorMargin, Math.Abs(LastMovement)) / _errorMargin; addition += bonus * bonusFactor; if (lastHitObject.HyperdashDistance <= 10) { additionBonus += 0.3 * bonusFactor; } } addition += 7.5 * Math.Min(Math.Abs(LastMovement), Constants.NormalizedHitobjectRadius * 2) / (Constants.NormalizedHitobjectRadius * 6) / sqrtTime; } if (lastHitObject.HyperdashDistance <= 10) { if (!lastHitObject.HyperDash) { additionBonus += 1; } else { Offset = 0; } addition *= 1 + additionBonus * ((10 - lastHitObject.HyperdashDistance) / 10); } addition *= 850.0 / Math.Max(time, 25); Strain = lastHitObject.Strain * decay + addition; }
public static OsuPixel GetPoint(List <OsuPixel> points, double length) { List <double> xVals = new List <double>(), yVals = new List <double>(); foreach (var point in points) { xVals.Add(point.x); yVals.Add(point.y); } var x = MathUtlity.Catmull(xVals, length); var y = MathUtlity.Catmull(yVals, length); return(new OsuPixel(x, y)); }
void UpdateHyperDashDistance() { double lastDirecetion = 0d; double halfPlayerWidth = PlayerWidth / 2; halfPlayerWidth *= 0.8; double last = halfPlayerWidth; for (int i = 0; i < DifficultyHitObjects.Count - 1; i++) { var cur = DifficultyHitObjects[i]; var nxt = DifficultyHitObjects[i + 1]; double direction; if (nxt.HitObject.x > cur.HitObject.x) { direction = 1; } else { direction = -1; } double timeToNext = nxt.HitObject.Offset - cur.HitObject.Offset - 4.166667; double distanceToNext = Math.Abs(nxt.HitObject.x - cur.HitObject.x); if (Math.Abs(lastDirecetion - direction) == 0) { distanceToNext -= last; } else { distanceToNext -= halfPlayerWidth; } if (timeToNext < distanceToNext) { cur.HyperDash = true; last = halfPlayerWidth; } else { cur.HyperdashDistance = timeToNext - distanceToNext; last = MathUtlity.Clamp(cur.HyperdashDistance, 0, halfPlayerWidth); } lastDirecetion = direction; } }
void CalcBezier(List <OsuPixel> points) { var order = points.Count; var step = 0.25 / Constants.SliderQuality / order; double i = 0; int n = order - 1; while (i < 1 + step) { double x = 0, y = 0; for (int p = 0; p < n + 1; p++) { var a = MathUtlity.Combine(p, n) * Math.Pow(1 - i, n - p) * Math.Pow(i, p); x += a * points[p].x; y += a * points[p].y; } var point = new OsuPixel(x, y); Position.Add(point); i += step; } }
void HandleHitObject() { var hitObjs = BaseBeatmap.HitObjects; foreach (var hitObject in hitObjs) { CatchHitObject catchHitObject; if (hitObject.HitObjectType == HitObjectTypes.Spinner || hitObject.HitObjectType == HitObjectTypes.BananaShower) { continue; } if (hitObject.HitObjectType == HitObjectTypes.Slider || hitObject.HitObjectType == HitObjectTypes.JuiceStream) { dynamic j; if (hitObject is JuiceStream stream) { j = stream; } else { j = hitObject as Slider; } double repeat = j?.RepeatTime ?? throw new InvalidOperationException(); double pLen = j.Length; var tmPt = GetAllTimePoints(hitObject.Offset); ValueObserver <double> tickDistance = ValueObserver <double> .FromValue((100 * BaseBeatmap.SliderMultiplier) / BaseBeatmap.SliderTickRate); if (BaseBeatmap.BeatmapVersion >= 8) { tickDistance /= (MathUtlity.Clamp(-1 * tmPt[CatchTimePointType.RawSpm], 10, 1000) / 100); } var curvePoints = new List <OsuPixel>(j.CurvePoints); var sliderType = j.CurveType; if (BaseBeatmap.BeatmapVersion <= 6 && curvePoints.Count >= 2) { if (sliderType == CurveTypes.Linear) { sliderType = CurveTypes.Bezier; } } if (curvePoints.Count == 2) { if (Math.Abs((int)(j.Position.x) - curvePoints[0].x) == 0 && Math.Abs((int)(j.Position.y) - curvePoints[0].y) == 0 || (Math.Abs(curvePoints[0].x - curvePoints[1].x) == 0 && Math.Abs(curvePoints[0].y - curvePoints[1].y) == 0)) { curvePoints.RemoveAt(0); sliderType = CurveTypes.Linear; } } j.curvePoints = curvePoints; j.CurveType = sliderType; catchHitObject = curvePoints.Count == 0 ? new CatchHitObject(hitObject) : new CatchHitObject(hitObject, tmPt, Difficulty, tickDistance); } else { catchHitObject = new CatchHitObject(hitObject); } CatchHitObjects.Add(catchHitObject); MaxCombo += catchHitObject.GetCombo(); } }