Рисование пунктирных границ

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

В местах, где у двух округов общая граница, вы просто рисуете границу дважды. В отсутствие эффектов частичной прозрачности и с твердым пером это не проблема.

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

alt text

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

Как / должно программное обеспечение для визуализации карт предотвращать появление подобных артефактов?


person Doug McClean    schedule 10.09.2009    source источник


Ответы (5)


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

person cdonner    schedule 10.09.2009
comment
Это работает, но разделение его на отдельные сегменты означает как очень большое количество сегментов, так и довольно сложную систему для распространения того места, где вы находитесь в шаблоне тире, при переходе от одного сегмента к соединяющему (что-то, что обрабатывается GDI +, включая правильное сглаживание, если прорисовывать целые контуры). - person Doug McClean; 11.09.2009
comment
Хорошо, если вы не хотите терять позицию в узоре, можете ли вы переключиться на прозрачное перо над уже нарисованными сегментами? Я не думаю, что ваша точка зрения верна, потому что, если у вас есть две линии, сходящиеся в одну, шаблон может быть непрерывным только для одной линии (той, которую вы нарисовали первой), а не для обеих. - person cdonner; 11.09.2009
comment
Я думаю, что путаница здесь заключается в разногласиях по поводу того, что составляет сегмент. В действительности полилинии намного более изрезаны, чем на образце изображения выше, и имеют множество изгибов и поворотов в местах, отличных от пересечения с другими округами. Если мы разделим его на каждый маленький прямой сегмент, это приведет к появлению множества мест, где узор будет потерян. Вы правы, что на стыке он может быть непрерывным только для одной или другой линии, хотя это не так уж и важно. - person Doug McClean; 11.09.2009
comment
Я не говорю, что вам нужно разбивать его на каждый сегмент, просто вам нужно удалить сегменты, перекрывающие другие. Предполагая, что соседние полилинии имеют общие точки, вы можете определить все линейные сегменты в полилинии и сохранить их в списке. Сегменты нужны только для сравнения, а не для рисования. Затем вы подготавливаете следующую полилинию и сравниваете каждый сегмент полилинии с тем, что вы уже нарисовали. Если есть совпадение, вы удаляете затронутые сегменты из полилинии. Вы можете столкнуться с ситуациями, когда оставшаяся полилиния не является смежной. - person cdonner; 12.09.2009
comment
Только после этого вам нужно разбить его на несколько полилиний. - person cdonner; 12.09.2009

Ваш узор кисти окрашивает некоторые пиксели в черный цвет, а некоторые пиксели оставляет без изменений. Вместо того, чтобы оставлять пиксель в покое, можете ли вы настроить узор кисти, чтобы эти пиксели были окрашены в белый цвет (или любой другой цвет вашего фона)?

Другой вариант - всегда рисовать границы округа дважды - один раз сплошным белым узором, а второй - рисунком кисти по вашему выбору.

person mob    schedule 10.09.2009
comment
Это умное решение, но оно не подойдет для чертежей со сглаживанием. Вы всегда получаете пиксельный мусор по краям. - person David Rutten; 11.09.2009
comment
Сглаживание - это проблема, да, потому что сплошной белый цвет нежелателен, мне нужно, чтобы слои внизу были видны там, где нет тире. - person Doug McClean; 11.09.2009
comment
Хотя ... если я сделаю весь рисунок, а затем всю композицию, вместо композиции во время рисования, сплошной белый, а затем пунктирный план может работать очень хорошо. Хорошая идея! - person Doug McClean; 11.09.2009
comment
Осторожно. Похоже, вы все усложняете, чтобы решить эту проблему определенным образом. Было бы гораздо предпочтительнее каким-то образом найти способ не рисовать эти перекрывающиеся сегменты для начала. - person David Rutten; 11.09.2009
comment
Согласен, Дэвид, но я подумал, что стоит указать на то, что эта идея действительно может сработать, поскольку я в спешке неточно сказал, что это невозможно. - person Doug McClean; 11.09.2009

Я предполагаю, что они разбивают свои границы на сегменты, а затем удаляют перекрытия.

Это в основном геометрическая проблема, а не проблема рисования.

person David Rutten    schedule 10.09.2009
comment
Правда, это в основном геометрическая задача. Я рассматривал возможность предварительной обработки границ в базе данных, чтобы удалить такое дублирование, но это привело к дублированию данных (или со сложной схемой учета), потому что мне нужны сами многоугольники, чтобы выполнять заливки, тесты пересечения и тесты членства. - person Doug McClean; 11.09.2009
comment
Я не пробовал, но если бы я попробовал, я бы подошел к этому так: 1) Создайте класс, который представляет один отрезок линии, то есть 4 числа, которые описывают координаты начальной и конечной точек. 2) Создайте метод, сравнивающий два из этих сегментов (добавьте некоторый допуск к сравнению). Убедитесь, что они считаются идентичными, даже если они движутся в противоположных направлениях. 3) При рисовании создайте словарь всех сегментов и проверяйте каждый новый сегмент по словарю. Если это сработает, вы можете решить эту проблему без каких-либо операций пересечения геометрии. - person David Rutten; 11.09.2009
comment
Верно, но вы не можете просто создать словарь, а затем перебирать его, рисуя сегменты, потому что (по крайней мере, для моих данных) сегменты имеют тенденцию быть небольшими по сравнению с шаблоном тире (порядка половины расстояния повторения или меньше). Затем вам нужно вернуть их в какой-то порядок, чтобы образец тире совпадал на границах сегментов. - person Doug McClean; 11.09.2009
comment
Хорошо, тогда ты облажался. Вам нужно будет каким-то образом найти перекрытия между двумя заданными полигонами и вырезать общий бит ... Я вам не завидую. - person David Rutten; 11.09.2009
comment
Ага, это подводит итог. :) - person Doug McClean; 11.09.2009
comment
В последнем предложении вы могли взорвать свои многоугольники, удалить все повторяющиеся сегменты, а затем снова объединить результаты. По крайней мере, это исправит непрерывность вашего рывка. - person David Rutten; 11.09.2009
comment
Это хорошая идея, и если бы я расширил класс сегментов в вашем примечании выше, включив указатели на предыдущий / следующий сегменты (их может быть больше двух, если один или несколько концов сегмента являются соединением), это может даже не быть слишком трудно. Я собираюсь изучить это и, возможно, записать это как другой ответ. Спасибо, Дэвид. - person Doug McClean; 12.09.2009

Вместо пунктирной линии вы можете использовать стиль Zip-a-tone, например:

alt text

Zip-a-tone - это графический материал, представляющий собой липкий лист пластика с обычным (пригодным для печати) узором из точек на нем. Чтобы использовать его, вы должны были положить большой лист на свой рисунок и вырезать его вокруг тех областей на рисунке, которые вы хотели бы затонировать, а затем отклеить части, которые вам не нужны.

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

Угловые линии немного сложны, но в основном вы представляете, как края линии прорезают пиксели, и, таким образом, вы рисуете их с соответствующим оттенком степени, а не полностью черным (в случае линии 45 градусов здесь пиксели нарисованы с помощью RGB (170, 170, 170), но любой угол может быть отображен с соответствующими оттенками).

Я не уверен, сможет ли GDI + сделать это легко с помощью текстурированных кистей, но возможно. В противном случае вам придется его кодировать. Преимущество этого метода перед сплошными серыми линиями состоит в том, что это позволит просвечивать часть фона.

person MusiGenesis    schedule 11.09.2009
comment
Мне нравится ваш стиль, и я проголосовал за него, но этот стиль в значительной степени предписан стандартом и многолетней практикой, поэтому я думаю, что мне нужно использовать более сложный подход к идентификации повторяющихся сегментов. Думаю, вы можете сделать это с помощью текстурированных кистей довольно легко. - person Doug McClean; 11.09.2009
comment
@Doug: да, текстурированные кисти делают это автоматически (я только что попробовал). Я думал, что, возможно, текстурированная кисть будет давать погрешности размером менее одного пикселя в зависимости от того, где были нарисованы линии и формы, но она рисует все из одного мозаичного листа растрового изображения текстуры a la zip-a -тон. - person MusiGenesis; 11.09.2009
comment
@Doug: ваша задача может показаться очень болезненной. Что делать, если две линии частично перекрываются? - person MusiGenesis; 11.09.2009
comment
Я думаю, что мы собираемся выполнять обнаружение в автономном режиме, когда мы выполняем все остальные проверки топологии геоданных, поэтому, если они частично перекрываются, мы будем жаловаться картографам и заставим их так или иначе сшить их. К сожалению, во многих наших входных данных граница A находится на одной стороне реки, а граница B находится в нескольких десятках метров с другой стороны, а не по центру, поэтому потребуется разумный объем работы по очистке. Это нормально, нам приходилось делать аналогичные вещи раньше, чтобы исправить другие проблемы с топологией. - person Doug McClean; 11.09.2009

Это интересный вопрос, о котором я никогда особо не задумывался. Я думаю, что единственное реальное решение - это визуализировать всю сложную фигуру как серию линий или путей, которые нигде не перекрываются. Я не удивлен, что GDI + не справляется с этой ситуацией автоматически.

person MusiGenesis    schedule 10.09.2009
comment
Полностью. Я вообще не виню GDI +, я просто пытаюсь понять, как другие справились с этой ситуацией. - person Doug McClean; 11.09.2009
comment
Это интересная проблема, хотя я, вероятно, просто использовал бы для этого сплошную светло-серую (серую?) Линию. Я признаю, что это полный обман. :) - person MusiGenesis; 11.09.2009