Gcode tools разработка внутренних функций

Обсуждение установки, настройки и использования LinuxCNC. Вопросы по Gкоду.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Gcode tools разработка внутренних функций

Сообщение Nick »

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

Задача #1

Собственный офсет
На данный момент используется офсет от inkscape (тот который dinamyc offset, он отличается от Контур->офсет). Но он часто дает плохие результаты и результат нельзя сразу же обработать. поэтому нужен свой офсет!

Решенные задачи

Пока нет, но мы будем стремиться заполнить этот список по самое не хочу :)!
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Итак оффсет...

Оффсет кривой безье делается, как оказываеься просто:
Берем параметрическую запись и к ней добавляем ее производную умноженную на радиус офсета.

Затем нужно соединить все концы соседних сегментов. Соединять нужно дугами окружностей.

Далее необходимо сделать клиппинг. Для этого необходимо найти все пересечения каждого сегмента получившейся кривой с каждым сегментом кривой.
Эта проблема самая сложная, пересечений у двух сегментов может быть аж до 9 штук. Но ведь кто-то это решил :). Можно как вариант прошариться по коду инкскейпа.

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

Итак, как можно отделить решения? Наверняка количество решений зависит от значения первой и второй производных у(t) по х(t). Причем если вторая производная не меняет свой знак, то сегмент не меняет вогнутости => количество точек пересечения уменьшается. Т.е. если мы разобьем сегменты в точках изменения второй производной, то количество возможных точек пересечения должно уменьшится до 4.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

root писал(а):Наверняка количество решений зависит от значения первой и второй производных у(t) по х(t). Причем если вторая производная не меняет свой знак, то сегмент не меняет вогнутости => количество точек пересечения уменьшается. Т.е. если мы разобьем сегменты в точках изменения второй производной, то количество возможных точек пересечения должно уменьшится до 4.
Хотя тут тоже не все так просто, y(x) это не функция, т.к. у(х) может иметь несколько значений для разных x :(...
Можно рассмотреть поверхность следующего вида и искать ее нули:
bezier offset 0001.png (3408 просмотров) <a class='original' href='./download/file.php?id=502&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (13.96 КБ)</a>

Код: Выделить всё

F(t_1,t_2) = sqrt{(x_1(t_1)-x_2(t_2))^2 + (y1_(t_1)-y_2(t_2)^2)}
Формула оффсета проста:
bezier offset.png (3408 просмотров) <a class='original' href='./download/file.php?id=501&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (27.98 КБ)</a>
, где P(t) - это искомая кривая. НО есть маленькое "но", такая кривая не всегда будет кривой Безье того-же порядка.....

Код: Выделить всё

{%OMEGA}(%rho, P(t)) = P(t) + %rho{(y'(t), -x'(t))} over {sqrt{x'(t)^2+y'(t)^2} } 
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

На счет построения оффсета, как я писал выше кривая полученная при помощи упомянутого выражения не будет кривой безье и еоэтому эту кривую нужно найти. При выполнении функции гравировки мы уже искали значения коэффициентов кривой безье по заданным четырем точкам. Этот метод можно применить и здесь, однако остаются вопросы.
1. По заданым четырем точкам мы можем построить только одну кривую. При этом точки должны быть вида (t, x, y), т.е. для заданного t определяем x и y. Исходя из описанной формулы это мы сделать можем. Нужно только определиться с точками t.
2. Что будет если полученные оффсеты в выбранных точках t будут пересекаться (это будет происходить когда радиус кривизны кривой будет меньше радиуса оффсета)?
3. Будет ли полученная кривая искомым отступом?
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Итак, начата разработка вспомогательных функций офсета.
1. Пересечение двух кривых Безье.
Реализация выполнена следующим образом :
Контуры разбиваются на сегменты и ищется пересечения всех сегментов друг с другом.
Сначала рекурсивно разбиваем каждый контур на две части и смотрим пересекаются ли bounds каждой из частей, если пересекаются продолжаем разбиение. (если пересекаются контуры то и их баунды пересекаются). Рекурсия продолжается до достижения заданной глубины разбиения (Можно сделать различную глубину для различных контуров).
Затем каждый из конечных кусочков кривых заменяем прямыми отрезками и ищем их пересечения. (Кстати спорный вопрос, может этого делать не нужно т.к. эти отрезки могут не пересекаться, когда контуры будут пересекаться.)
Затем уточняем каждое из полученных пересечений методом Ньютона. (Через уточнение решения системы двух кубических уравнений от двух переменных).

Остается вопрос определения типа точки пересечения - это пересечение или касание.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Теперь оффсет...

Вот, что пока получается:
0042 gcodetools offset.png (3363 просмотра) <a class='original' href='./download/file.php?id=538&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (162.56 КБ)</a>
Осталось всего-то ничего - join и клиппинг :).
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Итак офсет готов, хотя к нему нужно будет добавить одну оптимизацию. Join тоже готов. Но его нужно протестировать.
Clipping еще дорабатывается. Пересечение и само пересечение уже есть нужно написать процедуруткоторая определяет какие части нужно отрезать, а какие оставить. Завтра буду целые сутки ехать в поезде, может что-нибудь наклепаю.
Попутно несколько усовершенствовал процедуру нахождения расстояния от точки до кривой.
Push и картинки будут когда приеду.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Итак, первые результаты:
21 Контур офсет с шагом 10.
Время выполнения 231 секунда . Многовато :roll: ... Но это пока не проводилось никаких оптимизаций!
gcode bezier offset (3337 просмотров) <a class='original' href='./download/file.php?id=540&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (434.65 КБ)</a>
gcode bezier offset

Ревизия 98

Чуть-чуть готовый офсет :)
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Итак, разработка собственного офсета подходит к концу!!! :) :) :)
Из недостатков:
1. Медленная работа. Но в нашем случае риалтайм не обязателен, поэтому на данный момент можно оставить как есть. Возможно, потом напишем отдельный модуль на си который будет делать офсет заданной кривой гораздо быстрее.
2. Пока не работает с самопересекающимися контурами. Как вариант решения можно разбивать контур в местах самопересечения. Эта задача не совсем тривиальна и поэтому пока не реализована. Возможны случаи, когда кривую не получится разбить на несколько не пересекающихся контуров.
Преимущества по сравнению с существующим:
1. Настраиваемая точность. Хотя на момент тестирования и разработки точность выставляется 0.5, получившийся офсет гораздо точнее инкскейповского офсета.
2. Отсутствие артефактов. Этим обуславливается возросшее время вычисления. Для каждой точки офсета вычисляется расстояние до начальной кривой. Т.к. эта задача алгебраически не решается, то приходится искать расстояние вычислительными методами, которые требуют время.
3. Возможность использовать офсет внутри gcodetools! Теперь мы сможем создавать фаски всего одним нажатием клавиши, также это позволит автоматически делать чистовой проход и т.д.

Что необходимо доделать:
1. Ориентация кривой и ее субконтуров. Необходимо для правильного определения направления офсета.
2. Автоматическое вычисление радиуса офсета.
3. Офсет самопересекающихся кривых.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Done in 425.998970985 sec
Total offsets count 125
На счет отсутствия артефактов я погорячился, они есть, но они внутри обрабатываемой части...
Вложения
0047 gcode tools offset.png (3314 просмотров) <a class='original' href='./download/file.php?id=546&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (309.63 КБ)</a>
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Урааа!!! Я кажется придумал, как избавится от этих артефактов!!!
Они появлялись из-за сложности задания критерия "входит ли субконтур в офест или нет". Сложность заключается в том, что есть много "не точных" вычислений и много аппроксимаций.

С самого начала создаем оффсет сегмента кривой, в положении его начальной и конечной точки мы можем быть уверенны, т.к. они вычисляются алгебраически. Но, положения каждой точки офсета неточно, т.к. это аппроксимация. Также в процессе офсета, сегмент начальной кривой разбивается на более маленькие для достижения большей точности. В точках офсета начала и конца этих маленьких сегментов мы тоже уверенны - они рассчитаны алгебраически.
Далее мы разбиваем полученный офсет на куски всеми точками пересечения офсета сегмента и офсета остальной кривой.
И наконец-то нам нужно определить какой из этих кусков принадлежит офсету, а какой нет (находится ближе чем нужно).
Критерий:
Если у куска есть контрольные точки посередине - проверяем расстояние от контрольных точек до кривой. (оно должно достаточно точно совпадать).
Если у куска нет контрольных точек - тогда проблема. Т.к. он может быть получен из пересечений двух офсетов двух сегментов и не содержать ни одной "точной" точки. Что делать? Увеличивать допуск? Тогда в офсет могут попасть нежелательные сегменты. Не увеличивать, тогда мы можем исключить правильный сегмент.
Вот мое решение:
Делаем обратный офсет точки середины куска (reverse_offset). Он должен оказаться достаточно близко к исходной кривой. Далее находим ближайшую к reverse_offset точку на кривой. И делаем ее офсет (real_offset). real_offset - это достаточно точный офсет кривой в нужной точке. Если расстояние от кривой до real_offset лежит в заданных границах, то кусок часть искомого офсета.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Новые результаты:
1. Изменена функция клиппинга. Большинство ненужных частей отрезается без использования сложных вычислений.
2. Увеличена скорость работы алгоритма.

Вроде, качество офсета изменилось в лучшую сторону.

Итак, несколько результатов офсета:

Осторожно картинки большие от 0,6 до 2 Мб!

Офсет с шагом 1 всего 33 офсета время выполнения 227 сек.
0052 gcode tools offset.png (3288 просмотров) <a class='original' href='./download/file.php?id=552&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (629.13 КБ)</a>
И два офсета с шагом 10 (внутрь и наружу) время выполнения около 20-30 секунд.
0054 gcode tools offset.png (3288 просмотров) <a class='original' href='./download/file.php?id=553&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (678.35 КБ)</a>
0053 gcode tools offset.png (3288 просмотров) <a class='original' href='./download/file.php?id=554&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (291.4 КБ)</a>
100 офсетов с шагом 1 время выполнения 196 секунд.
0055 gcode tools offset.png (3288 просмотров) <a class='original' href='./download/file.php?id=555&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (1.69 МБ)</a>
12 офсетов с шагом 1 за 15 секунд.
Вложения
0056 gcode tools offset.png (3288 просмотров) <a class='original' href='./download/file.php?id=556&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (246.67 КБ)</a>
Аватара пользователя
DMexico
Опытный
Сообщения: 149
Зарегистрирован: 13 мар 2010, 21:39
Репутация: 7
Откуда: Киев
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение DMexico »

Есть ли в Inkscape или GCT функция которая возвращает среднюю линию между линиями обводки? Сделал вручную, но как-то непрофессионально это.
Вложения
Средняя линия вручную (2509 просмотров) <a class='original' href='./download/file.php?id=4067&sid=45cce6e78a979f40a8b61da79c10bff9&mode=view' target=_blank>Загрузить оригинал (188.29 КБ)</a>
Средняя линия вручную
Мнение автора может не совпадать с мнением редакции
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Gcode tools разработка внутренних функций

Сообщение Nick »

Есть engraving он делает примерно то же самое, но линия будет идти два раза (туда и обратно) и будет подходить ко всем углам (хотя, это можно настроить)...
Ответить

Вернуться в «LinuxCNC»