// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Linq; namespace osu.Game.Rulesets.Difficulty.Utils { public static class DifficultyCalculationUtils { /// /// Converts BPM value into milliseconds /// /// Beats per minute /// Which rhythm delimiter to use, default is 1/4 /// BPM conveted to milliseconds public static double BPMToMilliseconds(double bpm, int delimiter = 4) { return 60000.0 / delimiter / bpm; } /// /// Converts milliseconds value into a BPM value /// /// Milliseconds /// Which rhythm delimiter to use, default is 1/4 /// Milliseconds conveted to beats per minute public static double MillisecondsToBPM(double ms, int delimiter = 4) { return 60000.0 / (ms * delimiter); } /// /// Calculates a S-shaped logistic function (https://en.wikipedia.org/wiki/Logistic_function) /// /// Value to calculate the function for /// Maximum value returnable by the function /// Growth rate of the function /// How much the function midpoint is offset from zero /// The output of logistic function of public static double Logistic(double x, double midpointOffset, double multiplier, double maxValue = 1) => maxValue / (1 + Math.Exp(multiplier * (midpointOffset - x))); /// /// Calculates a S-shaped logistic function (https://en.wikipedia.org/wiki/Logistic_function) /// /// Maximum value returnable by the function /// Exponent /// The output of logistic function public static double Logistic(double exponent, double maxValue = 1) => maxValue / (1 + Math.Exp(exponent)); /// /// Returns the p-norm of an n-dimensional vector (https://en.wikipedia.org/wiki/Norm_(mathematics)) /// /// The value of p to calculate the norm for. /// The coefficients of the vector. /// The p-norm of the vector. public static double Norm(double p, params double[] values) => Math.Pow(values.Sum(x => Math.Pow(x, p)), 1 / p); /// /// Calculates a Gaussian-based bell curve function (https://en.wikipedia.org/wiki/Gaussian_function) /// /// Value to calculate the function for /// The mean (center) of the bell curve /// The width (spread) of the curve /// Multiplier to adjust the curve's height /// The output of the bell curve function of public static double BellCurve(double x, double mean, double width, double multiplier = 1.0) => multiplier * Math.Exp(Math.E * -(Math.Pow(x - mean, 2) / Math.Pow(width, 2))); /// /// Smoothstep function (https://en.wikipedia.org/wiki/Smoothstep) /// /// Value to calculate the function for /// Value at which function returns 0 /// Value at which function returns 1 public static double Smoothstep(double x, double start, double end) { x = Math.Clamp((x - start) / (end - start), 0.0, 1.0); return x * x * (3.0 - 2.0 * x); } /// /// Smootherstep function (https://en.wikipedia.org/wiki/Smoothstep#Variations) /// /// Value to calculate the function for /// Value at which function returns 0 /// Value at which function returns 1 public static double Smootherstep(double x, double start, double end) { x = Math.Clamp((x - start) / (end - start), 0.0, 1.0); return x * x * x * (x * (6.0 * x - 15.0) + 10.0); } /// /// Reverse linear interpolation function (https://en.wikipedia.org/wiki/Linear_interpolation) /// /// Value to calculate the function for /// Value at which function returns 0 /// Value at which function returns 1 public static double ReverseLerp(double x, double start, double end) { return Math.Clamp((x - start) / (end - start), 0.0, 1.0); } } }