Предыстория.
У меня давно была идея попробовать написать одну игру, имеющую отношение к гонкам. Сейчас в очередной раз решил попробовать.
Задача такая: гоночный автомобиль едет по некой траектории, которая задается сплайном (*). Каждой точке сплайна соответствует некоторая величина кривизны траектории. Кривизна участка траектории ограничивает скорость, с которой автомобиль может двигаться по этому участку. Для того, чтобы автомобиль проехал трассу с максимальной скоростью, я придумал примерно такой алгоритм (*):
- рассчитать максимальную скорость для каждого участка траектории
- затем для каждого участка рассчитать максимальную скорость с учетом того, что возможное торможение автомобиля ограничено техническими параметрами автомобиля, поэтому тормозить надо начинать заранее (и рассчитать, когда именно)
- затем рассчитать фактическую скорость каждого участка с учетом мощности двигателя
Теперь к сути вопроса. Для задания траектории я выбрал сплайн Акимы (где-то попалась статья со сравнением разных типов сплайнов, этот показался самым привлекательным). Код (он у меня на java) не привожу, во-первых, потому что его много, и вряд ли кто-то захочет в нем разбираться, а во-вторых, мне кажется, что проблема в математической части решения. Но если кто-то захочет - могу выложить. Дальше порядок такой:
- задаю опорные точки
- массив опорных точек с координатами

преобразую в два массива

и

, где

,

равно расстоянию от точки

до

- для каждого участка дуги рассчитываю коэффициенты функций

и

- затем сплайн (для упрощения расчетов вывода на экран) аппроксимируется ломаной линией: для каждой дуги я беру параметр

, изменяю его от

до

c шагом

, где

- некоторое произвольное число (10, 20 или 30 обычно). Для каждого такого значения

вычисляю

и

, по получившимся точкам

строится ломаная. Выглядит она как-то так:

(Цветом показана кривизна, чем краснее цвет, тем меньше радиус кривизны)
- далее беру уравнение эволюты (взял в
Википедии):


По этим уравнениям для каждой точки

рассчитываю координаты соответствующей точки эволюты. Вообще я считал, что если взять некоторое значение параметра

и найти координаты соответствующей точки сплайна (

), затем по формуле выше рассчитать координаты точки эволюты (

) при том же значении

, то найденная точка

будет центром касательной окружности, а точкой касания будет

. Но сейчас подумал, что у меня нет оснований так считать. Правильное ли это предположение?
- далее для каждой пары точек (точка сплайна + точка эволюты) я рассчитываю расстояние между ними, беру (пока с потолка) некоторое значение предельной силы трения и рассчитываю максимальную скорость в данной точке. Но дальше возникает проблема. На рисунке выше представлен кусок сплайна. Вот так для него выглядит распределение максимальной скорости вдоль траектории:

По оси абсцисс отложен номер промежуточной точки. Участок кривой между двумя опорными точками делится на 30 частей, соответственно каждая 30-я точка на графике соответствует опорной точке, все остальные точки - промежуточные. Тут видно два пика в районе второй и четвертой опорных точек - то есть в этих местах происходит небольшой излом. Для расчета оптимальной скорости автомобиля надо убрать по возможности такие скачки скорости. Буду рад любым советам...
(Наверное, может возникнуть вопрос, а с чего я вообще решил, что построенная таким образом кривая будет удовлетворять моим требованиям? Да, собственно, ни с чего. Просто не задумывался над этим. Я так понимаю, придется все сначала переделывать с другим типом сплайнов.)
_________
Знаком (*) обозначены вопросы, которые формально являются оффтопиком, но их тоже можно обсудить.
(P. S.)