Login
Задачка
6061 просмотров
Перейти к просмотру всей ветки
in Antwort alex445 20.05.25 21:21
Ну нужно просто поболтать немного ![]()
Давай сформулируем универсальную функцию, которая будет:
- Поддерживать движение в любом направлении.
- Без лишних параметров, но с понятным принципом работы.
- Интуитивно понятной для пользователя.
Вот готовый вариант:
public static float Fraction(float a, float b, float current)
{
if (a == b)
throw new ArgumentException("A и B не должны быть равны, иначе длина отрезка будет нулевой.");
return (current - Math.Min(a, b)) / Math.Abs(b - a);
}
🔄 Как это работает?
- Отрезок может быть задан в любом порядке (
aиb), то естьaне обязан быть меньшеb. - Определяем начальную точку (
Math.Min(a, b)) → от неё считаем долю. - Используем абсолютную длину отрезка (
Math.Abs(b - a)), чтобы не было привязки к направлению.
📌 Примеры работы:
Fraction(-1, 3, 2); // 0.75 (обычное направление)
Fraction(3, -1, 2); // 0.25 (обратное направление)
Fraction(10, 5, 7); // 0.6 (считаем от 5 к 10)
Fraction(5, 10, 7); // 0.4 (считаем от 10 к 5)
Теперь длина отрезка всегда положительна, направление определяется само собой, а функция остаётся универсальной и понятной. Никаких дополнительных параметров, но логика счёта полностью прозрачна.
Если current выходит за пределы [a, b], то в текущем варианте результат может выйти за границы [0,1]. Например:
Fraction(-1, 3, 5); // 1.5 (current больше b)
Fraction(-1, 3, -3); // -0.5 (current меньше a)
🛠 Как исправить?
Если нужно ограничить результат диапазоном [0,1], можно добавить Clamp:
public static float Fraction(float a, float b, float current)
{
if (a == b)
throw new ArgumentException("A и B не должны быть равны.");
float fraction = (current - Math.Min(a, b)) / Math.Abs(b - a);
return Math.Clamp(fraction, 0, 1); // Ограничение от 0 до 1
}
📌 Теперь:
Fraction(-1, 3, 5); // 1 (больше b → прижмётся к 1)
Fraction(-1, 3, -3); // 0 (меньше a → прижмётся к 0)
Теперь функция не выйдет за пределы и гарантированно вернёт значение от 0 до 1.
Zurück