рисование линий различной толщины
От: ssvSerge  
Дата: 27.08.23 13:20
Оценка:
Привет всем.

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

Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела. Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры". Сейчас в каждой позиции рисуем круг нужного диаметра. Это решает все вопросы, но эффективность оставляет желать лучшего.

Есть ли более адекватные подходы?
Re: рисование линий различной толщины
От: vsb Казахстан  
Дата: 27.08.23 13:31
Оценка:
Здравствуйте, ssvSerge, Вы писали:

S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).


S>Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела. Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры". Сейчас в каждой позиции рисуем круг нужного диаметра. Это решает все вопросы, но эффективность оставляет желать лучшего.


S>Есть ли более адекватные подходы?


Адекватный подход называется антиалиасинг. Для линий тут всё просто. Представьте себе, что рисуете две параллельные линии нулевой толщины на листе клетчатой бумаги. Клетки это пиксели, расстояние между линиями это целевая толщина конечной линии, линии это границы конечной линии. И потом закрашиваете клетки на листе клетчатой бумаги. Если клетка целиком между этих двух границ поместилась, значит закрашиваете в чёрный цвет. Если половина клетки внутри линии, значит закрашиваете серым цветом. Ну и так далее, чем больше клетки внутри линии, тем черней цвет.

Это пример для белого и чёрного. С любыми другими цветами аналогично. Как правильно рассчитывать переход между цветами — там тоже есть нюансы, ну для начала можно просто по каждой компоненте RGB смасштабировать.

Про алгоритмы: я знаю такой: Википедия: Алгоритм Ву может и получше есть.

Ещё нюанс — для целочисленных значений толщин линий при рисовании горизонтальных и вертикальных линий я бы советовал округлять координаты так, чтобы размытия не было.
Отредактировано 27.08.2023 13:32 vsb . Предыдущая версия .
Re: рисование линий различной толщины
От: Stanislav V. Zudin Россия  
Дата: 27.08.23 13:37
Оценка:
Здравствуйте, ssvSerge, Вы писали:

S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).


S>Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела. Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры".


А прозрачность учитываете? Навскидку, если рисовать линии параллельно, достаточно Брезенхема с прозрачностью или Ву

PS. Неужели АГГ или Skia не вписываются по ресурсам?
_____________________
С уважением,
Stanislav V. Zudin
Re: рисование линий различной толщины
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 27.08.23 18:21
Оценка:
Здравствуйте, ssvSerge, Вы писали:

S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).

А давай ты подробнее расскажешь что вообще есть на устройстве, например, есть ли там GLES?
S>Есть ли более адекватные подходы?
Как выше сказали, портануть SKIA/ANGLE и поверх него может много чего работать.
Sic luceat lux!
Re[2]: рисование линий различной толщины
От: ssvSerge  
Дата: 27.08.23 22:08
Оценка:
Здравствуйте, vsb, Вы писали:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Неужели АГГ или Skia не вписываются по ресурсам?

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

vsb>Адекватный подход называется антиалиасинг.

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

vsb>Клетки это пиксели, расстояние между линиями это целевая толщина конечной линии, линии это границы конечной линии.

При этом получаются разрывы.

Спасибо за алгоритм Ву. Я посмотрю что из него можно вытащить.
Re[3]: рисование линий различной толщины
От: Vzhyk2  
Дата: 30.08.23 18:08
Оценка:
S>Быть может я поступил неверно и слишком упросил описание проблемы. Вообще говоря, из отдельных сегментов рисуется полилиния. И желательно сохранить толщину как на самой линии, так и в точках изгиба. Круги отлично решают все проблемы, но ценой повторных заливок.
Скорее всего вам нужно под вашу задачу оптимизировать этот алгоритм с окружностями. Если совсем не тянете, то стукайтесь в личку, можно попытаться глубоко поковырять за деньги (валюту).
Re: рисование линий различной толщины
От: B0FEE664  
Дата: 31.08.23 16:05
Оценка:
Здравствуйте, ssvSerge, Вы писали:

S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).

S>Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела.
Толстая прямая — это прямоугольник.
S>Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры".
Обычно (зависит от алгоритма), если сдвигать концы отрезка только на x+1 или y+1 (но не одновременно), то дыр не будет.
Так что если занести все точки отрезка в массив, а потом отрисовывать эти точки несколько раз последовательно сдвигая все x на +/-1 (потом все y на +/-1) вдоль одной из сторон прямоугольника, то получится сплошной толстый отрезок. Учтите, что графику без антиалиасинга (сглаживания) большинство не любит, а мелкие элементы вообще не могут быть корректно отрисованы без сглаживания при поворотах.
И каждый день — без права на ошибку...
Re: рисование линий различной толщины
От: swame  
Дата: 01.09.23 13:56
Оценка:
Здравствуйте, ssvSerge, Вы писали:

S>Привет всем.


S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).


S>Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела. Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры". Сейчас в каждой позиции рисуем круг нужного диаметра. Это решает все вопросы, но эффективность оставляет желать лучшего.


S>Есть ли более адекватные подходы?


Если нет желания возиться с алгоритмами, круги можно отрисовать в буфер битмап и оттуда рисовать копированием.
Re: рисование линий различной толщины
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.09.23 04:45
Оценка:
Здравствуйте, ssvSerge, Вы писали:
S>Делаем графическое приложение для носимого устройства. Использование сторонних графических библиотек очень нежелательно (сильно ограничены ресурсами).
S>Неожиданной задачей оказалось рисование полилиний толщиной больше одного пиксела. Если рисовать несколько линий рядом, то и толщина меняется и появляются "дыры". Сейчас в каждой позиции рисуем круг нужного диаметра. Это решает все вопросы, но эффективность оставляет желать лучшего.
Эмм, выглядит так, что эти два утверждения несколько противоречат друг другу.
Какими именно ресурсами вы ограничены?
Я правильно понимаю, что вы разменяли размер кода на быстродействие, и получили компактный код, который слишком медленно рисует?

Я бы на вашем месте всё же посмотрел на существующие библиотеки.
Та же AGG умеет делать ровно то, что вам нужно. Её основной недостаток, АФАИК — в том, что она разработана для старого оборудования, и не умеет в современный SIMD и графические акселераторы.
То есть для вас это как раз то, что нужно — ведь у вас носимое устройство, на котором вряд ли есть все эти штуки.

А про размер кода — там же всё в исходниках, можно попробовать выкинуть из неё всё, кроме рисования полилиний. Очень вряд ли вы сможете написать сильно более эффективную реализацию за разумное время.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: рисование линий различной толщины
От: Vzhyk2  
Дата: 14.09.23 06:39
Оценка:
S>Я бы на вашем месте всё же посмотрел на существующие библиотеки.
S>Та же AGG умеет делать ровно то, что вам нужно. Её основной недостаток, АФАИК — в том, что она разработана для старого оборудования, и не умеет в современный SIMD и графические акселераторы.
Вау, кто-то подхватил библиотеку McSeem? Либа была крутая в свое время.
Re[3]: рисование линий различной толщины
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.09.23 11:11
Оценка:
Здравствуйте, Vzhyk2, Вы писали:
V>Вау, кто-то подхватил библиотеку McSeem? Либа была крутая в свое время.
Ну я вижу туда какие-то коммиты. Но сам не пользуюсь, степень живости оценить не могу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: рисование линий различной толщины
От: Vzhyk2  
Дата: 15.09.23 08:03
Оценка:
S>Ну я вижу туда какие-то коммиты. Но сам не пользуюсь, степень живости оценить не могу.
Я к тому, что этого парня многие на кывте знали. Грамотный и интересный парень был. Умер, а дело его живет. Это приятно, что дело его кто-то подхватил.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.