Pull to refresh

Comments 18

Можно посмотреть с другой стороны: задать вектор скорости и вращать его по необходимости. И если уж мы говорим про игры, то самый частый случай — вращение в сторону цели с фиксированной скоростью, то необходимо на каждой итерации всего лишь вычислять знак полуплоскости цели от вектора скорости.

Спасибо за статью.

Когда реализовывал линейное движение по кривой (все примерно также) возник очевидный недостаток — такая кривая статична, пришлось придумывать как асинхронно пересчитывать равномерные точки.
Но как приятный бонус — можно по равномерно распределенным точкам воспроизвести кривую, и сглаживать ее сколько угодно.

Что-то меня интуитивно тянет к дифференциальной геометрии и формулам Френе. Кмк красивое решение должно быть там. Как результат естественной параметризации.

ответ на одни вопросы порождает другие:
крайняя правая точка кривой с учётом её тангенса создаёт нереальную для полёта самолёта кривую. Вот о таких моментах и их автоматическом исправлении путём добавления новых точке-автокоррекции тангенса, других уловках было бы интересно почитать а если ещё с учётом, чтоб это решалось в рамках навмеша было бы вообще замечательно(применять поиск пути и трейсить каждый кадр — решение очевидное и общеизвестное но явно не удобное и чересчур дорогое, интересно получить решение именно путём правки траектории и тангенса)
Не обнаружил по приведённой ссылке процедуры, решающей ту же задачу. Единственный похожий метод public Vector3 GetHermiteAtTime(float timeParam) выполняет простую линейную интерполяцию. Не там смотрю?

Надеюсь эту статью прочтут в Anywayanyday.


А то их скринсэйвер жутко бесит угловатой траекторией.

image

А нельзя реализовать управляемое моделирование движения самолета, задав ему точки, через которые он должен пролететь? Тогда траекторию будет задать чуть сложнее, зато двигаться он будет реалистичнее.
Можно, конечно, но тогда хорошо бы ему еще задать интерполяцию вращения по всем осям, и задавать точки маршрута с учетом совокупного воздействия подъемной силы и гравитации.
Алгоритм выглядит весьма неоптимальным — много раз (столько, сколько итераций в методе Ньютона) считается длина дуги от начальной точки, вместо того, чтобы считать длину дуги на интервале. И похоже это число итераций метода Ньютона весьма велико — возможно всегда равно 100 и условие
if (Mathf.Abs(f) < 0.01f)
      break;

никогда (или очень редко срабатывает). Иначе не знаю как объяснить такую медленную скорость работы — почти 1 секунда для 100000 точек.
Количество итераций методом Ньютона в среднем составляет от 1 до 3. И при численном интегрировании не имеет разницы в количестве вычислений, считается ли длина дуги от начала или на участке. Разве что точность будет чуть выше.
Имелось ввиду, что алгоритм можно переписать так, чтобы не считать длину дуги от начальной точки на каждой итерации, а использовать значение длины, вычисленное на предыдущей итерации, и считать длину участка дуги между предыдущей точкой и текущей.

Я тоже решал такую задачу. Сделал так: разбил кривую на несколько частей, посчитал длину каждой части численно и построил интерполяционный полином, который выдавал t(L), где L — необходимая длина от начала сплайна, t аргумент функции сплайна. У меня кривая задавалась кубическим b-сплайном, полином, который выдавал t(L) был четвертой степени, но так как t(0)=0, то хватило четырех коэффициентов. Таким образом сплайн и полином L(t) имели по 4 коэффициента, их удобно было в шейдеры передавать. Плюс моего метода ещё и в том, что коэффициенты t(L) можно посчитать заранее, а не в рантайме.

Вроде бы спираль Эйлера (спираль Корню, клотоида) позволяет вычислять точки на себе в зависимости от пройденного расстояния вдоль кривой, а не на основе абстрактного t, как у Безье.


Когда-то пытался сделать сплайны на основе спиралей Эйлера как раз для простоты равномерного движения — пускать паровозики с вагончиками, но сходу что-то не пошло и сделал просто на дугах окружностей.

Интересная тема, не сталкивался раньше. Но, как мне кажется, это будет потеря вариативности в угоду меньшей вычислительной сложности.
Нас же интересует обратная операция, то есть вычисление значения аргумента по заданной длине дуги
Таким образом, задача превратилась в задачу поиска корня уравнения, с чем может прекрасно справиться метод Ньютона.

Такую задачу ещё можно решать бинарным поиском.
Выходит, конечно же, медленнее, но для интервала длины 1 число итераций в худшем (любом) случае O(log(1/precision)) и нет проблем со схожденим, как в методе Ньютона. Для дебага — самое то.

Конечно, она и решается бинарным поиском, в случае, если метод Ньютона даёт неприемлемый результат. Аргумент в пользу того, чтобы не решать её бинарным поиском целиком — если у нас есть возможность «бесплатно» использовать информацию о производной функции, почему бы её не использовать? Ведь в общем случае метод Ньютона сходится быстрее.

Спасибо, но обозначения немного путанные мне кажется. Что такое X и Y не понял, и s и t. Под интегралом тоже путанно, там наверное должно быть dY/d\tau. И упомянуть что у нас переменные это вектора в 3d тоже не помешает.

Sign up to leave a comment.

Articles

Change theme settings