Диагональная линия визирования с двумя углами

9

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

Край прямой видимости

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

Желаемый результат

Какой самый быстрый способ изменить линейный алгоритм Брезенхэма, чтобы решить эту проблему? Если нет хорошего решения, есть ли лучший подходящий алгоритм? Любые идеи приветствуются. Обратите внимание, что решение также должно поддерживать 3d.

Редактировать: Моим простым решением было проверить, закрыты ли оба угла при изменении координат x и y линии. Рабочий исходный код и интерактивную демонстрацию готового продукта см. По адресу http://ashblue.github.io/javascript-pathfinding/.

Пепельно-синий
источник
2
Имеет ли значение, если вы переключаете начальную и конечную точку? Возможно, тогда вы могли бы просто принять результаты, если оба вычисления возвращают беспрепятственную линию видимости. Вы также можете найти некоторые статьи LOS полезными на RogueBasin.
Таладор
1
В любом случае, эти два черных блока с диагональю 4-5 не связаны в первую очередь со стеной, и я говорю это потому, что вы неявно допускаете движение по диагонали. Вы должны либо выровнять эту диагональ по квадрату, чтобы сделать ее смежной стеной, либо сделать так, чтобы ваш ходок по линии выровнялся с диагональными движениями, вместо того чтобы идти по диагонали, как 2-3 и 4-5.
Патрик Хьюз
Перевернуть это звучит как хорошая идея, но это не решает проблему. Единственное, о чем я могу подумать, это проверить и проверить, пуст ли один из двух углов. Кажется, дорогой, хотя.
Эш Блю
5
«Кажется, дорого» никогда не бывает достаточным оправданием, чтобы не попробовать что-то. «Будет слишком дорого», как правило, при условии, что вы можете доказать, что что-то будет слишком медленным.
Мокоша
3
Единственное изменение в требуемом алгоритме состоит в том, что если и X, и Y изменяются на одном и том же шаге, то сначала измените X, а затем измените Y, это исключит диагонали.
Патрик Хьюз

Ответы:

7

Эрик Липперт написал превосходную серию по созданию прямой видимости в C # с помощью Shadow Casting на прямоугольной плоской сетке.

Среди других вопросов, Эрик имел дело с различными вопросами, на которые необходимо ответить о требованиях к прямой видимости, которые дают разные результаты, и приводит примеры нескольких разных результатов. Одна из статей подробно рассматривает обстоятельства «заглядывания в угол», возникшие в ранней версии его алгоритма.

Я адаптировал алгоритм Эрика к шестиугольной сетке здесь , и успешно использовал его на больших гексагональных сетках (> 400 х 700) с широким радиусом видимости (> 60 гексов). Эта реализация рассчитывает и отображает полное поле обзора так быстро, как я могу моргать, используя один процессор i7. Это, безусловно, достаточно быстро для любых целей, которые я собираюсь использовать.

Обновление - Линия визирования с высотой: реализация
шестигранной сетки, связанная с вышеупомянутой, вычисляет линию визирования с высотой, а не только препятствия. В примечаниях к документации также обсуждается дополнительное решение, которое должно быть принято в отношении расчета высоты: высота цели и высота наблюдателя. Выбор по умолчанию - сделать оба равных, что создает симметричное поле зрения, но можно выбрать и землю, и глаза наблюдателя на землю. (Код с открытым исходным кодом по лицензии MIT)

Питер Гиркенс
источник
Я действительно копаю Shadow Casting, но столкнулся с проблемой. Возникли проблемы с поиском какой-либо информации о масштабировании алгоритма для работы с осью Z. Извините, что упомянул об этом, но есть ли у вас какие-либо предлагаемые ресурсы, чтобы заставить его работать в 3d?
Эш Блю
@AshBlue: см. Приложение выше
Питер Гиркенс,
Я смотрю на вашу кодовую базу. В нем есть что-то интересное, но я не вижу алгоритма рисования линий, подобного Брезенхэму, адаптированного к гексам. Ты делаешь это с LOS?
MLProgrammer-CiM
@EfEs: FieldOfView - возвращаемый объект; ShadowCastingFov * .cs генерирует поле зрения путем отбрасывания теней. Если у вас есть конкретные вопросы по поводу кода, их лучше всего задать в разделе «Обсуждения» на сайте; На более общие вопросы я с удовольствием отвечу здесь.
Питер Гиркенс
@PieterGeerkens Вы можете найти вопрос здесь gamedev.stackexchange.com/questions/57087/…
MLProgrammer-CiM
1

Что, если для расчета LOS у вас есть отдельная сетка с «более высоким разрешением», которая заполняет угловые промежутки. Я думал что-то вроде этого:

введите описание изображения здесь

Слева - оригинальный блок из 4 квадратов.

Справа - версия с «высоким разрешением», поскольку вы можете видеть, что каждый исходный квадрат был разделен на четверти, и один из углов был заполнен. Я не уверен, что алгоритм для его генерации был создан вручную, но он может быть предварительно вычислен с текущей карты.

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

Davy8
источник
Уверен, что более высокое разрешение будет выглядеть точно так же, как оригинал. При разделении сетки на меньшую сетку вы получаете такое же визуальное представление, только с меньшей сеткой. Каждый квадрат становится 4 меньшими квадратами в одном месте.
MichaelHouse
@ Byte56 Правильно, я имел в виду, что после разделения будет применена дополнительная логика, чтобы добавить дополнительные блоки к этой копии. Логика для этого - упражнение, оставленное читателю.
Davy8
Вы можете легко создать сетку высокого разрешения, размывая оригинал. Затем определите порог, скажем, 0.5для заполненных ячеек с высоким разрешением или нет. Таким образом, использование сетки с высоким разрешением мне кажется довольно хакерским.
Данияр