Дано:
Остров невыпуклой формы, заданный множеством отрезков, образующих его контур. Без самопересечений, но потенциально может состоять из нескольких компонент связности.
Найти:
1.(обязательно) Для каждой точки пространства требуется установить *сглаженное* расстояние до поверхности острова, широту.
2.(желательно) Для каждой точки также установить положение по второй координате, что-то вроде долготы или угла.
Иллюстрация:
чёрным показан сам остров, серым показаны изолинии (1), оранжевым — изолинии (2).
Требуется, чтобы алгоритм работал в неудобных случаях впуклой и выпуклой границы, давая аккуратный результат вблизи самого острова:

Задача (1) нужна для автоматического расчёта направления гравитационных волн в районе острова, (2) нужна для аккуратного придания формы в направлении, перпендикулярном береговой линии.
Моё текущее решение похоже на это: http://outerra.blogspot.co.nz/2011/02/ocean-rendering.html я просто строю distance field для всего острова, потом его блюрю. Градиент по этому дистанс филду и будет направлением движения волн. Недостаток подхода в том, что чтобы получить достаточно сглаженные волны, блюрить надо много и долго. Второй недостаток — я не получаю информацию (2), вообще никак.
Чтобы получить (2), я для дистансфилда также определял одномерную координату ближайшей к нему точки контура. К сожалению, этот способ даёт очень плохие результаты внутри вогунтых углов, потому что создаётся линия резкого перехода этой координаты, которую необходимо очень долго блюрить.
Suslik
2 раза построить дистанс филд подойдет?
Сначала строишь первый дистанс филд, и для него определяешь границу, на которой у тебя будут начинаться волны:
Черное - твой остров, контур - граница полученная после дистансфилда. Потом ты все пиксели которые за границей инвертиуешь, и строишь дистан филд уже для этого:

MrShoor
я не понял, чем это поможет отцу русской демократии. во впуклых участках обычно артефактов больше и к решению п.2 этот способ, вроде, тоже не приближает.
Suslik
> во впуклых участках обычно артефактов больше и к решению
Вот я сделал в krtia glow на 50 пикселей для исходного "острова".
Потом инвертнул пиксели. Все что было ровно 255 255 255 сделал черным:
И вот снова сделал glow на 50 пикселей от инвертнутого изображения:
Где тут артефакты на впуклых участках?
Вот исходный остров добавил на фон:
А вот красным выделена зона, где чисто белый цвет, 255 255 255:

Suslik
> и к решению п.2 этот способ, вроде, тоже не приближает.
Возможно изолинии можно будет посчитать из соотношения расстояния первого и второго дистанс филда (типа lerp-ом от весов дистанций), но тут я не уверен. Нужно сесть и на бумажке прикинуть.
MrShoor
> Где тут артефакты на впуклых участках?
Тут нет впуклого участка.
На силовые линии похоже => можно попробовать найти координаты и величины зарядов эквипотенциальная поверхность для которых является чем-то похожим на береговую линию.
Adler
> На силовые линии похоже => можно попробовать найти координаты и величины
> зарядов эквипотенциальная поверхность для которых является чем-то похожим на
> береговую линию.
да, я тоже думал в этом направлении. но не совсем понятно, как это эффективно посчитать.
MrShoor
> Вот я сделал в krtia glow на 50 пикселей для исходного "острова".
ты сделал очень узкую полоску для полностью выпуклого многоугольника. с таким случаем прекрасно справляется и обычный дистанс филд, построенный для исходного острова. артефакты случаются, если строить широкий дистанс филд(до радиуса порядка размера самого острова) и если у острова есть впуклые части вроде гавани.
Suslik
> до радиуса порядка размера самого острова
А к чему такой огромный дистанс филд то? Может я чего-то не понимаю.
p.s. Я бы вообще хейтмапой пользовался для прибоев, а не дистансфилдами. Тогда автоматом получаешь еще кучу других плюсов. Напомни почему нельзя это делать?
MrShoor
> А к чему такой огромный дистанс филд то? Может я чего-то не понимаю.
потому что остров/полуостров может быть протяжённым и тонким. например, 30 метров в ширину и волны должны начинаться с такого же расстояния.
MrShoor
> p.s. Я бы вообще хейтмапой пользовался для прибоев, а не дистансфилдами. Тогда
> автоматом получаешь еще кучу других плюсов. Напомни почему нельзя это делать?
под водой в существующих ассетах хайтмеп достаточно быстро обрывается(пары-тройки метров от берега), потому что дна всё равно не видно, плюс поверхность дна в районе обрыва совершенно кривая.
Suslik
> 30 метров в ширину и волны должны начинаться с такого же расстояния.
Ну так ты первым дистансфилдом экспандишь его на 30 метров. Второй дистансфилд делает шринк на 30 метров. Я не вижу проблемы.

MrShoor
я не понимаю, в чём смысл двух дистансфилдов-то? почему не 1? почему не 42? каким образом результат будет отличаться и чем он будет лучше? к тому же, повторюсь, во всех впуклых областях будут артефакты, которых нет, если просто блюрить обычный дистансфилд. фактически всё, что делает такое преобразование — это создаёт неопределённую область во внутренних углах, больше ничего не меняя. я таким алгоритмом дырки закрашивал в растре.

наконец, техническая сложность реализации такого подхода в моём случае — мне необходимо во втором проходе строить дистансфилд для растра, это будет итеративный процесс за логарифмическую сложность. в первом проходе я строю дистансфилд для множества видимых отрезков, образующих береговую линию, аналитически точно за O(1).
Suslik
> я не понимаю, в чём смысл двух дистансфилдов-то? почему не 1? почему не 42?
> каким образом результат будет отличаться и чем он будет лучше?
Фактически ты делаешь expand, а потом shrink. Все углы скругляются до радиуса твоего экспанда/шринка. Узкие и маленькие участки уходят. Был угловатый остров:
А становится остров со сглаженными углами.
Suslik
> к тому же, повторюсь, во всех впуклых областях будут артефакты
Вот там где у тебя знак вопроса - у тебя должен быть второй дистансфилд. Фактически первый дистансфилд - ты экспандишь на величину, от которой у тебя начинаются волны. Второй дистансфилд у тебя безразмерный (много больше твоего экспанда) и ты ведешь волны по нему.
короче, давайте ещё идеи. я не проникся построением растров дистансфилда. давайте подумаем в направлении того, что исходный контур задан множеством сцепленных отрезков. может, из этого что-то можно придумать?
Тема в архиве.