Алгоритм сжатия векторной графики с потерями #735226


#0 by Супер король
Рисуем мышкой любую линию. Кривую или ровную. Линия состоит из точек. Точек слишком много чтобы их координаты запомнить. Можно эти точки заменить соединенными отрезками, ломаной прямой, тогда нужно будет только запомнить координаты узловых точек, которых гораздо меньше, но качество при этом потеряется. нужно придумать алгоритм, при котором качество "на глаз" будет теряться одинаково не зависимо от кривизны и сложности линий. То есть если тупо соединять прямыми каждую десятую точку, то на плавных почти ровных участках с большим радиусом кривизны качество будет теряться меньше чем на крутых загибах маленького радиуса. Как решить эту задачу на лету? Прямо во время рисования чтобы кривая заменялась на отрезки.
#0 by Супер король
Рисуем мышкой любую линию. Кривую или ровную. Линия состоит из точек. Точек слишком много чтобы их координаты запомнить. Можно эти точки заменить соединенными отрезками, ломаной прямой, тогда нужно будет только запомнить координаты узловых точек, которых гораздо меньше, но качество при этом потеряется. нужно придумать алгоритм, при котором качество "на глаз" будет теряться одинаково не зависимо от кривизны и сложности линий. То есть если тупо соединять прямыми каждую десятую точку, то на плавных почти ровных участках с большим радиусом кривизны качество будет теряться меньше чем на крутых загибах маленького радиуса. Как решить эту задачу на лету? Прямо во время рисования чтобы кривая заменялась на отрезки.
#1 by Супер король
Можно усложнить задачу используя вместо прямых отрезков кривые второго, третьего порядков. Сплайны. Безье.
#2 by Лодырь
Ставишь точку 0 в точке начала кривой, через некий шаг(S) нарисованной кривой ставишь точку 1 и так далее. Потом апроксимируешь чем хочешь.
#3 by Asmody
Так работает выделение контура в фотошопе и гимпе. Исходники гимпа открыты, можешь там посмотреть.
#4 by Супер король
слишком сложно разбираться в коде ради просто алгоритма
#5 by Супер король
Я думаю что критерия добавления каждой следующей точки должно быть два: 1. Угол отклонения следующего отрезка относительно предыдущего превысил определенный максимум. Это для мелких резких поворотов. 2. Нужно ограничить не только угол, но и расстояние следующей точки от прямой предыдущего отрезка. Это для больших плавных линий.
#6 by Крошка Ру
Что ты велосипеды изобретаешь? Почитай про сплайны и возьми наиболее подходящий метод.
#7 by Лодырь
Не мешай человеку ) Он науку двигает )
#8 by Масянька
Если я сейчас вспомню свой диплом... :) Можно по принципу тахеометрической съемки: есть исходная нулевая точка съемки. От нее откладываем точки (X, Y, угол (если нужно)). После нанесения всех точек - соединяем. Упрощенно :)
#9 by Масянька
+ Насколько я помню, есть еще минимальный шаг для точек.
#10 by Супер король
кто-нибудь кроме понял ?
#11 by iamnub
Чо тут понимать, название темы идиотское. Сжимать векторную графику - ты сам-то понял?
#12 by iamnub
Ты же не в 1С свои сплайны рисовать?
#13 by iamnub
#14 by Lama12
Сжимать векторную графику не получится. Ее суть в том, что полученное изображением можно масштабировать без потерь качества. То, как поставлена задача, говорит о том, что изображение векторным не будет. Да и что мешает рассмотреть алгоритмы поиска функции интерполяции, возможно на описание такой функции уйдет меньше информации, хотя х.з.
#15 by Супер король
Как рисовать сплайны я знаю. Вопрос был по каким точкам их рисовать.
#17 by vde69
вообще я решал сабж как в 2д так и в 3д... это классический интерпритарор CNC при решении я намеренно отказался от кривых, все делал отрезками, это на порядок упростило задачу...
#19 by Garykom
Объясни нафейхуа? В смысле векторная графика занимает минимум, в отличие от растровой. Зачем её еще и сжимать? Это к тому что тему, назвал неправильно, тебе нужен алгоритм аппроксимации произвольных кривых - такое легко решается сплайнами. Суть в чем у тебя есть шаблоны кривых (разных) и можно любую свою произвольную кривую разбить на нужные кусочки, найти эти кусочки на шаблонах и указать координаты оттуда.
#20 by Супер король
станки с ЧПУ сплошные. Ты о чем?
#21 by Супер король
не надо с растровой сравнивать, тогда не будет казаться что она мало места занимает
#22 by Drac0
Помню, в универе одногруппник делал курсовую по кривым Безье (вроде 2-го порядка). Высокая точность и производительность решения. Попробуй их замутить.
#23 by Супер король
ага, я именно их и использую.
#24 by vde69
дело все в том, что разные системы сплайны делают по разному, одна и таже модель в каде и максе будут отличны визульно для эксперта. простой пример - обводы автомобилей, опытный человек по внешнему виду машины может сказать в какой программе делалось... и тут дело не в разных теоретических алгоритмах а конкретной реалитзации...
#25 by Супер король
да пофиг на сплайны. С прямыми отрезками бы сначала разобраться.
#26 by Garykom
вообще то прямая это частный случай кривой )) вырожденный такой случай так что если разобраться с кривыми, то прямые тоже решены
#27 by Супер король
А по теме кто-нибудь может помочь?
#28 by Garykom
+ да ник конечно классный, вот только вопрос не соответствует )) ЗЫ если рисуем мышкой (или планшетом) то можно еще проще делать кодируем не линию а движения мышки (пера) а они чем могут быть описаны? радиус-вектор (угол и длина перемещения) и временем т.е. просто через интервал времени берем угол движения, и зная начальную точку, интервал и углы строим линию, дл контроля используем конечную точку завершения рисования (координаты как и начальной)
#29 by Garykom
а по теме ну не вижу проблемы как и прочие кто отписался, методов можно применить множество какой брать это уже на вкус
#30 by Супер король
Через интервал времени не подойдет. Если пользователь быстро будет дергать мышкой, можно упустить что-то заметное.
#31 by Супер король
Хоть бы один метод предложили.
#32 by Garykom
э? ты случаем или пользователь не учитель-монстр из ? чтобы на нескольких махах мышкой дрыгать )) под интервалом подразумевалась часть секунды...очень маленькая например 100 или даже 10 миллисекунд чем не устраивают и ? в курсе что есть проги для cnc-станков которые чертеж преобразуют в команды для станка?
#33 by vde69
1. метод правой руки (не путать с левой) :) 2. метод "усечения" 3. метод перебора 4. метод "строй и перестраивай" и т.д.
#34 by Супер король
в просто яндекс, ничего конкретного в я уже сказал чем не устраивает. интервалы не подойдут, так как не оптимальны.
#35 by Гёдза
Наверняка уже все придумано. Просто загугли
#36 by Супер король
пример: пользователь рисует прямую линию. Долго, медленно и старательно. вот она: _____________________________________________ на каждый пиксель уходит пять раз по 10 миллисекунд. Получается если делать интервалами времени, то объем данных будет в пять раз больше чем если бы использовали просто пиксели. Но правильное решение в данном случае было бы запомнить только первую точку и последнюю.
#37 by Гёдза
есть алгоритмы преобразования растра в вектор. Именно твой случай
#38 by Супер король
растр не рассматривается
#39 by Garykom
гыыы супер контраргумент только можно же вместо интервала, точнее проверку-обработку то делаем все равно по интервалу, но вот кусочки берем от их длины не? т.е. кусок меньше X то ждем пока будет >=
#40 by Гёдза
пользователь рисует линию - это и есть растр
#41 by Супер король
и чему равен Х? пользователь рисует загогулину и линию: @ _____________________________________ Так не пойдет
#42 by Супер король
это вектор
#43 by vde69
почитай твой случай это упрощенная частность триангуляции....
#44 by Супер король
зачем? наверное ты не правильно вопрос понял
#45 by vde69
я правильно понял, ты ресушь и тебе нужен векторы, хитрость в том, что нельзя расматривать дискретность по времени, каждый раз нужно откатывать немного назад и строить кусок до конца, это и есть "строй и перестраивай" пример нарисовал --~~~-- (3 вектора) потом добавил --~~~---- программа откатила последний вектор и проанализировала хвост заново, получили сново 3 вектора, но последний более длинный
#46 by Супер король
попонятнее можно? Вот пользователь рисует. появилась точка. потом вторая. потом третья. и так далее. в какой момент можно сказать что некоторые предыдущие точки делаем одной линией, и начиная с какой-то из точек начинаем следующую линию? И какую точку выбрать?
#47 by Супер король
Вот так например рисует: . . . . . . ..............
#48 by Супер король
[1c] . . . . . . .............. [/1c]
#49 by Супер король
[code] . . . . . . .............. [/code]
#50 by Супер король
[ахалаймахалай] . . . . . . .............. [/ахалаймахалай]
#51 by vde69
ты почитай... там все написано.... ты разрушаешь последние элемент и строиш новый, потом разрушаешь предпоследний и строишь новый, сравниваешь два результата, выбираешь лучший, если луший получился разрушением двух сегментов - продолжаешь разрушать и строить с третего и так далее...
#52 by Супер король
как сравнить какой результат лучше?
#53 by vde69
это тема отдельной БОЛЬШОЙ ветки.... для меня например было минимальные длины перпендикуляров опущеные из точек... опять-же в моих ссылках все это написано, особенно про ЧПУ...
#54 by Супер король
это я в писал. плюс еще минимальный угол отклонения
#55 by Rebelx
Мой вариант: Первый: Как определить, что точку можно удалить? Задаем максимальную погрешность берем три точки, строим прямую между первой и последней. Если максимальное отклоненение отрезка от точки меньше погрешности - среднюю точку можно удалить. Добавляем следующую точку для анализа и т.д. Дополнение: Можно попробовать сместить крайние точки в пределах погрешности, и тогда может быть средняя окажется лишней - см.выше.
#56 by Супер король
>> берем три точки Какие именно? Все подряд перебором? Нужен алгоритм наиболее простой, без переборов множества вариантов. Что-то вроде: Берем очередную точку, проверяем условие, если сработало то начинаем новый отрезок и продолжаеи, иначе просто продолжаем. Нужно только придумать условие
#57 by Rebelx
начиная с первой и вперед если без переборов - то представь ситуацию, 180 точек, отклонение каждой - 1гр., в пределах погрешности. Вместо полукруга получим прямую. Конечно можно хранить накопленную погрешность.
#58 by DrZombi
Что решить, куда решить? Сколько платишь, такой и алгоритм :) ...сдается мне, что товарищ в хочет халяву...
#59 by DrZombi
+Давай свой Код, вот тогда можно и обсудить :)
#60 by Супер король
отклонение первой точки 1гр, второй 2гр, третьей уже 3гр. и постоянно растет пока не достигнет максимальной погрешности
#61 by Rebelx
Погрешность 1гр, 180 точек, отклонение каждой - 0.5гр. Как без перебора? и возврата к предыдущим, только по двум точкам? Просто напиши номера точек, которые должны остаться. Усложним пример. Отклонения точек чередуются - +-1гр., отклонение в не допуска. между первой и второй, и предпоследней и последней - расстояние в 2 раза меньше остальных. - т.е. надо реализовать вырождение ломаной в прямую
#62 by Супер король
ты имеешь в виду вот так чередуются? -_-_-_-_-_-_-_-_-_- если отклонение вне допуска, то в прямую нельзя преобразовать. будет ломаная.
#63 by Rebelx
нет, VVVVVVVVVVVVVVVVVVVVVVVVV
#64 by Rebelx
VVVVVVVVVVVVVVVVVVVVVV
#65 by vde69
он не хочет читать и искать, он хочет готовое решение, он-же король :)
#66 by Супер король
ну да. по прежнему если отклонение вне допуска, то в прямую нельзя преобразовать. будет ломаная
#67 by Rebelx
первая и последняя - на оси ломаной. т.е. все точки в допуске
#68 by vde69
у тебя 2 разные задачи 1. векторизация 2. проблемма обработки больших массивов по этому твоя задача решается только применением двух алгоритмов одновременно... а ты обсуждаешь только один алгоритм....
#69 by Супер король
короче, нужна формула желательно состоящая из простых арифметических действий: Расстояние от точки до прямой заданной двумя точками.
#70 by Супер король
есть у кого ?
#71 by vde69
прервая ссылка зы если не может такую элементарную вещь найти в инете, то это ппц.... закрыть-бы ветку, да жалко, вроде люди хотели помоч....
#72 by Супер король
эта ссылка у меня цветом как уже просмотренная. Там нет ответа на мой вопрос.
#73 by Супер король
можно приближенную формулу, адаптированную для компа.
#74 by vde69
чем формула d = (AMy + C)/sqrt(AB) не подходит? наличием корня? или ты не знаешь как подставлять координаты?
#75 by vde69
d = (A My + C)/sqrt(A B)
#76 by Супер король
от корня могу избавиться возведя все это в квадрат. Для сравнения квадрат тоже подойдет. Но эта формула для прямой заданной уравнением, а не двумя точками. При выводе уравнения прямой добавятся куча других действий, что еще больше ее усложнит. А мне нужна очень простая формула, пусть даже с какой-то погрешностью но быстро рассчитываемая. Мне даже не нужно получить расстояние, а нужно узнать оно больше или меньше заданного числа. Я задал очень сложный вопрос, на который скорее всего нет простого ответа. Простые ответы типа   не предлагайте, я их и сам находил.
#77 by Супер король
Например sqrt(А^2 + B^2) можно упростить до А + В, такой точности вполне достаточно.
#78 by vde69
все просто... наличие тупого угла указывает, что точка "за" границами отрезка отрезок АБ, точка В, если один из углов АБВ или БАВ более 90 градусов - точка - за разумеется считать нужно в радианах, там нет пи
#79 by Супер король
каких углов? Углы не известны
#80 by vde69
а вообще я когда этим занимался активно использова понятие "четверти"...
#81 by Супер король
сам угол рассчитывать тоже не нужно, достаточно узнать синус угла, и сравнивать с синусом угла погрешности.
#82 by vde69
так посчитай... уверяю ты не сможешь обойтись пятью знаками... берешь бумагу, ручку, на ней ставишь кучу точек и выводишь уравнения, потом их упращаеш... другой путь - использовать готовые библиотеки третьего не дано...
#83 by Супер король
кто знает. Вдруг уже кто-то вывел решение этой задачи. Есть у алгоритма преимущество перед просто формулой - можно использовать условия, сравнения. Можно нарисовать окружность по точкам используя только сложение и сравнение
#85 by Супер король
хорошая ссылка. спасибо
#86 by Супер король
еще и в Красноярском крае. Вообще замечательно
#87 by Супер король
вот готовая формула: ( (ax-ox)*(by-oy)-(bx-ox)*(ay-oy) ) / sqrt( (ax-bx)*(ax-bx) + (ay-by)*ay-by) )
#88 by Супер король
Короче, другой алгоритм придумал: 1. Накапливаем сумму расстояний между точками, получаем пройденный путь. 2. Считаем расстояние между первой точкой и последней. 3. Сравниваем эти два результата. 4. Если они равны в пределах погрешности, значит пока линия можно считать что прямая. Погрешность может зависеть от длины отрезка, т.е. на коротких отрезках погрешность меньше, пропорциональна длине отрезка. 5. Если результаты сильно разные, завершаем старый отрезок и начинаем новый. Этот алгоритм лучше чем предыдущий тем что проще в понимании, а так же лишен недостатка когда пользователь рисует прямую линию и возвращается по той же прямой обратно. Что скажете? Какие недостатки могут быть?
#89 by vde69
плохой алгоритм.... но объяснять не буду, сам думай...
#90 by sda553
Фактически в векторной графике храняться координаты точки, R(вектор), Направление V вектор, и кривизна A. Модель очень подходит под физическое косочно-равноускоренное движение материальной точки. Или "лекало". Суть приближения состоит в том, чтобы превратить кривую в несколько переходящих друг в друга дуг окружностей. Для такого приближения, мы подставляем к исходной точке дугу окружности и увеличиваем радиус этой окружности пока 1. Отклонение от кривой, вычисленное методом наименьших квадратов на покрываемую длину кривой будет наименьшим, оставаясь при этом в рамках допустимого отклонения для этой степени сжатия. Таким образом алгоритм похож на действия человека, который подставляет к кривой лекало и двигает его, пытаясь получить максимальное приближение поверхности лекала к кривой на максимальный отрезок кривой, с некоторым, допустимым для данного человека, приближением
#91 by zulu_mix
чето тут велик конструируют с квадратными колесами. правильнее будет собрать матрицу данных и сжать ее LZ
#92 by Garykom
а я предлагаю нарисовать и сохранить в jpeg ... двуцветный сжатый jpg это никакой вектор не угонится за минимальностью ))
#93 by zulu_mix
как вариант. кстати, в постановке задачи было только сжатие ведь? нигде не сказано что он должен правильно разжиматься?
#94 by Супер король
метод наименьших квадратов плохо подходит, так как нужен быстрый метод, без пересчета всех точек при добавлении одной точки.
#95 by Супер король
это сжатие без потерь. Не годится
#96 by SeraFim
ахаха) вспомнил - была какая-то олимпиада. Нужно было написать алгоритм сжатия данных. Причем написать как архиватор, так и разархиватор. В итоге победила команда, которая написала копирование данных) Ни одна из других команд не смогла разархивировать свой алгоритм)))
#97 by Супер король
сделал тест. Одна черная линия на белом фоне. 10 тысяч байт файл получился ! ! ! Вместо 18 байт векторной графики - 10 тысяч! Зачем давать глупые советы?
#98 by Супер король
не нашел в нем ничего плохого. Что не так?
Тэги: Математика и алгоритмы
Ответить:
Комментарии доступны только авторизированным пользователям

Похожие вопросы 1С

В этой группе 1С