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