Вы на самом деле не дали достаточно информации, чтобы сказать, какой диапазон вам нужен, то есть ли он ограничен, хотите ли вы геометрическую прогрессию и т. Д.
Первое, что вы хотите сделать, это получить число, пропорциональное величине скорости, которую вы хотите потерять (она не должна быть такой же, но она должна уменьшаться с увеличением скорости, чтобы сделать ее пропорциональной вашей потере). Стандартный способ сделать это - взять ответное :
temp = 1 / currentVelocity;
Теперь для 100 у вас будет 0,01, для 200 - 0,005, для 300 - 0,0033 и так далее.
Теперь вам просто нужно настроить это число на то, что вы действительно хотите, умножив его. Так
k = 3000;
newVelocity = temp * k;
даст вам 20 за 300, но это даст вам 15 за 200, а не 10. Это может быть хорошо для вас, в этом случае вам не нужно читать дальше. Вы можете настроить k так, как вам нравится, но вы не можете получать числа так, как вам нравится, если вы не сделаете немного больше, например, реализуете геометрическую прогрессию или измените базу для увеличения. Я не буду вдаваться в геометрические прогрессии здесь, но если вы хотите изменить базу, вы делаете это следующим образом:
base = 100;
temp = 1 / (currentVelocity - base);
if (temp < 0) temp = 0; //adjust temp so never less than zero, cannot gain force!
k = 2000;
velocityLoss= temp * k;
if (velocityLoss > currentVelocity) //(1) or make currentVelocity an unsigned int
velocityLoss = currentVelocity; //(2)
Это предоставит вам диапазон, который вы изначально запрашивали в своем вопросе, 300 -> потеря 10, 200 -> потеря 20. FYI 100 -> потеря 40, и 50 -> потеря 80 (!), Что означает, что вы нужно ограничить вычитание - это то, что я сделал в строках (1) и (2).
Конечно, есть и другие способы решения всей этой проблемы, которые, я уверен, те, кто более математически искусен, чем я, опубликую здесь.
log(myVelocity + 1) * N
?