A * эвристика для создания линий Bresenham
Из того, что я понимаю о A * эвристике и как работает алгоритм Брешенема, это может быть невозможно, поскольку только текущее состояние и состояние цели передаются эвристической функции. Но, возможно, у кого-то есть умное решение этой проблемы.
Я использую A * для планирования пути на сетке, и мне нужна эвристика, которая приведет к лучшему пути следования линии Bresenham, когда есть свободные промежутки между текущим состоянием и целью или очередным поворотом препятствие.
Вот несколько изображений, чтобы проиллюстрировать проблему.
Манхэттенское расстояние:
Если бы движения в мире действовали как шашки на сетке, это было бы прекрасно, но я в конечном итоге собираюсь преобразовать траекторию A * в движения на непрерывной плоскости, так что это работает очень хорошо.
![The shortest path from red to green using the Manhattan distance heuristic]()
Евклидово расстояние:
Лучше, но все же не идеально. Обратите внимание на прямую линию в конце. Диагональ могла бы так же легко оставаться диагональной, что и я хочу.
![The shortest path from red to green using the Euclidian distance heuristic]()
Что я хочу:
Линии Бресенхама - это розыгрыш следующего хода или цели.
![The best path I actually want, which uses Bresenham lines to get to the goal]()
Я нашел здесь хороший ресурс, http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html, который касается того, что я ищу, но, похоже, работает только для рисования линий Брешенема от начала до цели. Я хочу, чтобы линии Bresenham рисовали на следующий поворот вокруг препятствия.
Любые идеи для хорошего подхода к этой проблеме?
Ответы
Ответ 1
Можете ли вы изменить функцию стоимости "на лету", чтобы стоимость перехода вперед увеличивалась с накопленной ошибкой?
Идея заключается в том, что в начале алгоритма вычислить DX и DY, как в стандартном Bresenham. (Предположим в остальной части примера, что DX > DY > 0. Измените соответственно для других направлений.)
Затем для каждого посещенного соседа node отследите ошибку Bresnaham:
if (neighbor.X > this.X)
neighbor.err=this.err+DY
else if (neighbor.Y > this.Y)
neighbor.err=this.err-DX
Затем измените свою функцию стоимости в пользу увеличения X, но добавьте if (err >= DX/2) then cost=cost+FACTOR
. На карте, где все остальные затраты равны, это должно отслеживать правильную линию.
Другая вещь, которая вам может понадобиться, - это специальная обработка, когда путь перемещается по препятствию, иначе вы могли бы получить странные дорожки, похожие на стены, похожие на "кросс-продукт с предметами", например, в вашей связанной статье. Вы могли бы справиться с этой ситуацией, пересчитав DX и DY всякий раз, когда сосед node не находится в направлении + X или + Y. (К сожалению, это, вероятно, требует отслеживания отдельных DX, DY и ошибок для каждого node, что может быть слишком большим объемом служебных данных)
Отказ от ответственности, я не реализовал алгоритм A * или Bresneham за многие годы. Вся эта идея может быть неработоспособной
Ответ 2
Пусть все ваши альтернативы перемещения будут углами, видимыми с вашей текущей позиции (или цели, если она видна), и как только вы найдете самый короткий путь, нарисуйте линии Bresenham между всеми вашими остановками.
Ответ 3
Можете ли вы использовать обнаружение столкновения с помощью алгоритма Брешенема, возможно, адаптивного Брешенема, например, с кривой заполнения пространства?
Ответ 4
Как описано в разделе "Разрыв связей" статьи, к которой вы привязались, возможно, вы могли бы добавить фактор эвристики, который близок к тому, что этот node лежит на линии между его родителем и целью. Таким образом, он предпочел бы оставаться на прямой линии, когда это возможно.