Написать о себе (Например: Программист)
0,0
рейтинг
4 декабря 2012 в 14:07

Разработка → Подделываем вашу подпись при помощи шарнирного механизма. Теорема Кемпе из песочницы

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


Теорема Кемпе


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




Многие математики считали, что проблема создания шарнирного механизма, рисующего идеальную прямую линию, является в принципе неразрешимой, пока в середине 19-го века не был открыт гениальный механизм Липкина-Посселье, который рисует точную прямую:

В этом механизме все палочки одинакового цвета имеют одинаковую длину. Доказать, что механизм действительно рисует прямую можно прямыми выкладками, как говорится, в лоб. Но люди, знакомые с преобразованием инверсии, могут увидеть довольно четкую логику в доказательстве. К моменту изобретения механизма Липкина-Посселье уже смазочные материалы были настолько хороши, что в технике могли обходиться без этого идеального преобразователя в прямолинейное движение. Ведь можно через еще одну палочку передавать почти прямолинейное движение на поршень. Эта палочка не будет всегда идеально параллельной направляющей поршня, но в этом ничего страшного нет. В итоге механизм Липкина-Посселье так и не нашел широкого применения в технике, но зато оказал огромное влияние на математику.
Через несколько лет математик-адвокат Кемпе приводит алгоритм, как абсолютно для любой алгебраической кривой на плоскости построить шарнирный механизм, который умеет рисовать только эту кривую и больше ничего не умеет. Иными словами, существует механизм, ограниченный в движении одной степенью свободы. Двигаясь вдоль этой степени свободы механизм рисует нашу алгебраическую кривую. Прекрасное изложение доказательства Кемпе я нашел в этой статье. Напомним читателю, что алгебраические кривые, о которых идет речь в теореме Кемпе — это кривые, заданные уравнением , где — любой многочлен. Например, — это окружность радиуса , — наклоненная прямая, — парабола. В своем доказательстве Кемпе использует много интересных идей, но ключевым инструментом построения является уже известный нам механизм Липкина-Посселье.

Процесс


Как только я узнал о теореме Кемпе, я сразу же захотел написать программу, в которой пользователь может нарисовать любую кривую, скажем свою подпись, а программа аппроксимирует подпись алгебраической кривой, а потом по алгоритму Кемпе построит шарнирный механизм, подделывающий ее. Мне очень хотелось сделать веб-приложение, чтобы пользователю не нужно было ничего устанавливать на компьютер, чтобы можно было зайти на сайт и запустить все «в один клик». Так как я не программист, то это еще было для меня прекрасной возможностью познакомиться с JavaScript и HTML5.
После того, как я выучил доказательство Кемпе, передо мной встала очень серьезная проблема:
как аппроксимировать подпись алгебраической кривой с хорошей точностью, быстро, да еще и на медленном JavaScript? Существует очень простой, но неподходящий нам способ аппроксимации кривой объединением маленьких окружностей, разбросанных вдоль кривой, как показано на картинке:

Каждая маленькая -ая окружность является, очевидно, алгебраической кривой, так как задается полиномиальным уравнением , где — центр окружности, а — ее радиус. Алгебраической кривой, очевидно, будет и объединение всех маленьких окружностей, так как это объединение будет задаваться полиномиальным уравнением . Но как вы видите, такой вид аппроксимации нам совершенно не подходит, потому что возникает очень много точек самопересечений. Хотелось бы иметь более «красивую» аппроксимацию. Оказывается, проблема «красивой» аппроксимации сложная как с математической точки зрения, так и с вычислительной. Чтобы как-то прочувствовать это, полезно представить алгебраическую кривую как пересечение поверхности и плоскости . Линия пересечения очень чувствительна к коэффициентам многочлена , она совершенно неконтролируемо может быть несвязной, иметь точки ответвлений, что и будет портить «красоту» аппроксимации.
После недели экспериментов с различными алгоритмами, все мои попытки хоть как-то аппроксимировать кривую оказались тщетными. Все алгоритмы работали очень медленно и плохо. Я почти сдался, предварительно запостив вопрос на mathoverflow, где традиционно сидит много профессиональных математиков. В вопросе я вскользь упомянул, что мне это нужно для того, чтобы подделывать подписи шарнирами. Каково было моё удивление, что через день-два мне ответил математик Михаил Капович. Ответил «не в бровь, а в глаз». Как оказалось, он когда-то занимался теоремой Кемпе и вместе с Джоном Миллсоном в своей статье доказал, что можно построить шарнирные механизмы не только для алгебраических кривых, но и для кривых, которые более естественно подходят для задач аппроксимаций, а именно, для кривых, заданных параметрически полиномиальными выражениями:





Такими кривыми проще простого аппроксимировать любые непрерывные кривые, в том числе и нашу подпись. Можно аппроксимировать так называемыми полиномами Чебышева, а можно сначала приблизить рядами Фурье, а потом тригонометрические функции в рядах Фурье приблизить рядами Тейлора. Получается, что вместо того, чтобы пытаться аппроксимировать кривую алгебраическими кривыми, лучше изменить само доказательство Кемпе и научиться строить шарнирные механизмы, умеющие строить более подходящие для задач аппроксимации кривые.
Вся эта история по ощущениям была похожа на находку огромного алмаза. Но, к своему стыду, я не до конца разобрался в той статье. Статья написана довольно сложно. Но сам факт того, что существует решение моей проблемы открыл мне глаза. Я сообразил, что незначительным изменением оригинального доказательства Кемпе можно строить шарниры, рисующие косинусоидальные тригонометрические кривые, то есть кривые вида





Такими кривыми даже еще легче аппроксимировать нашу подпись (теория рядов Фурье), чем кривыми со статьи Каповича-Миллсона. Действительно, из теории рядов Фурье следует, что на отрезке функции и можно разложить в ряд по косинусам. Для точности аппроксимации имеем:


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

Я очень долго думал размещать ли в этом посте алгоритм построения шарниров, которые и строят эти тригонометрические кривые. Потом я понял, что это добавит математической скучности в текст. Люди обычно не любят в текстах такого рода читать длинные доказательства. Поэтому я обойдусь просто ссылкой (upd: зеркало). Любопытные могут посмотреть.
A вот, собственно, и само приложение, которое подделывает вашу подпись: david.wf/linkage. (upd: зеркало) Прошу заметить, мышкой можно двигать конструкцию, а скроллером — приближать и удалять (upd: степень аппроксимации тоже можно менять специальным ползунком «approximation»). Приложение работает на современных браузерах, на старых я не тестировал. Меньше всего тормозит на хроме, так как только хром намного быстрее других браузеров рисует прямые (пруфлинк). Признаться, я потратил много сил на оптимизацию, чтобы ничего не тормозило на слабых компах, но, скажу честно, особых успехов не достиг. Еще раз подчеркну, шарнир, который строит программа ничего не умеет рисовать, кроме вашей подписи. Шарнир приводится в движение крутящимся синеньким треугольником — «двигателем».
Худавердян Давид @khdavid
карма
163,2
рейтинг 0,0
Написать о себе (Например: Программист)
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (123)

  • +6
    Подпись подделал.
    Завораживает.
    • –5
      Отлично сочетается с дабстепом. Например Xilent – Choose Me (Dubstep Mix). Всем отделом зависли минут на пять.
  • +9
    Выглядит совершенно фантастично. А есть ли у этой красоты хоть какое-нибудь практическое применение?
    • 0
      Думаю, если добавить устройство вывода и внести определенным образом описываемые погрешности в отображение подписи (к сожалению, я не эксперт, однако у экспертов, работающих в области сверки подписей, должны быть формализуемые и неформализуемые алгоритмы оценки принадлежности подписи), то устройство имеет более чем практическое применение, но, конечно, хотелось бы мнение автора
      • 0
        Я слышал ещё усилие нажатия на бумагу имеет значение. Неплохо бы и это предусмотреть.
        • +11
          Совершенно необязательно использовать шарнирный механизм для рисования кривой на бумаге: уверен, с этим отлично справится два электропривода, меняющие координаты (x,y). А электромагнит, к примеру, может менять давление пера. Современная механика и цифровое управление обеспечат отличную точность. Если же использоваться шарниры, то получится стим-панк техно-монстр для рисования одной кривой.
          На мой взгляд это исключительно теоретическая, но очень красивая работа. Как большая часть всей современной математики :E
          • +2
            Именно так это и делалось, на отечественном трехперьевом графопостроителе АП (номер не помню)
            Самое сложное было прикрепить шариковую ручку вместо родного чернильного пера.
            Сканировалась подпись, обводилась в автокаде — так сказать векторизация.
            Ну а дальше дело техники.
            • 0
              А русские пишут карандашом.
              А некоторые подписи стеклофонят :)
        • +3
          ещё усилие нажатия на бумагу имеет значение

          Совершенно верно. И еще множество признаков, по которым «компьютерную» подпись можно отличить от человеческой. Кстати, и полная идентичность двух подписей свидетельствует о том, что, по меньшей мере, одна из них поддельная.
          • 0
            Можно добавить погрешность… где то в узких местах
    • +12
      Конечно. С её помощью можно создать большую базу данных подписей реальных людей.
    • +13
      А есть ли у этой красоты хоть какое-нибудь практическое применение?


      У этой штуки нет никакого практического применения. Оно ей совершенно не нужно. Это чистая, незамутнённая красота. Часто ли встречаете такие теоремы, схему конструтивного доказательства которых можно и хочется закодировать?

      Кто говорил, что Хабр не тот? (Я говорил, что Хабр не тот.) Очень радуюсь, когда опровергают это утверждение.
      • –3
        торт
    • 0
      Автоперья: en.wikipedia.org/wiki/Autopen
      1803 год. Подписание множества писем президентов, книг фанатам и другие интересные варианты.
      Так что практические применения нашлись даже раньше описанных алгоритмов. :)
  • +29
    Даже лучше меня мою подпись рисует :)
    • +3
      Поддерживаю, подпись получилась более гладкой :) Завораживает…
  • +1
    Выглядит очень круто! Правда грузится очень медленно, хабраэффект.
    • +2
      После таких комментариев вообще не грузится :)

      А вообще выполнить такой шарнир натурно — вот и отличное подспорье кассирам и коммерческим директорам ;)
  • +14
    Круто! На очереди технология, которая из скана подписи делает при помощи 3D-принтера механизм для ее подделки :)
    • +1
      Круто! На очереди технология, которая из скана подписи делает при помощи 3D-принтера механизм для ее подделки :)

      А лучше КЛОН подписанта :)
      • +1
        не, не надо клон. Нужна только его подпись.
      • 0
        Мне тут от одного не избавиться, а вы второго предлагаете. Кормить кто будет?
  • +16
    Фантастика.
    Но даже для коротенькой прямой генерирует совершенно нереализуемые конструкции из сотен рычагов.
    • +2
      То самое хотел подметить
    • +3
      И для точки.
      • +1
        Зато какая красивая конструкция для точки получается! Да и движения…
    • +4
      Может необходимо добавить некоторое сглаживание еще при вводе?

      Идея и реализация — просто супер!
      Лучшая статья за последнее время!
  • +3
    Этот получаемый шарнирный механизм максимально простой или возможна оптимизация для уменьшения количества составляющих?
    • НЛО прилетело и опубликовало эту надпись здесь
      • +1
        Хех… Зато какое поле для генетических алгоритмов :)))
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Можно ведь просто отключать подачу чернил для имитации отрыва пера от бумаги.
  • +4
    Очень сильно срезает углы в некоторых местах.

    • +10
      Попробуйте увеличить степень аппроксимации — результат будет больше соответствовать Вашему рисунку.
    • +1
      При дефолтной «approximation: 20» из моей подписи (так же срезая углы и завитушки) получилось примерно то, что выходит у меня, когда расписываюсь небрежно. Реалистично :)
  • +4
    :-D А на моей подписи получился бред, три буквы превратились в волну… Надо было идти учиться на врача…
  • +37
    А я не смог мышкой свою подпись нарисовать.
  • +1
    Видимо, я один такой, кто не понял, как заюзать эту штуку, а не просто смотреть на крутящиеся многогранники…
    upd: ну да, надо же было прочитать, что написано в круге…
  • –1
    Подпись Магомета не подделывается
  • –1
    Впечатляюще!
  • +23
    • +37
      У вас подходящая аватара.
      Я даже сперва подумал, что то не аватар, а вы картинку вставили, чтобы выразить эмоции рисовальщика (или свои).
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        ага, и ник тоже по случаю подправил
    • +4
      почерком вы очень смахиваете на тестировщика ПО
      • +1
        Я дизайнер:)
  • +3
    А теперь нужно все это распечатать на 3D принтере и собрать вживую!
    • –2
      невозможно такой механизм построить
  • +1
    Теперь нужно добавить кнопочку «создать задание для 3D-принтера», чтобы экспортнуть в печать получившееся устройство из шарниров.
    • +3
      Обновлять комментарии… Обновлять комментарии… Обновлять комментарии… Обновлять комментарии…
  • +5
    Пробовал нарисовать прямую… мышкой,,, под линейку, чтобы увидеть гениальный механизм Липкина-Посселье, который рисует точную прямую в простейшем виде. I failed.
    • +1
      аппроксимация одним членом дает, в принципе, что-то похожее, только наворотов побольше
    • 0
      Можно просто аппроксимацию выставить в 1 :-)
  • +10
    А где можно будет скачать базу данных собранных подписей? :)
    • +6
      «Чтобы скачать что-нибудь ненужное базу данных, надо сначала создать базу данных, а у нас логинов нет...» (с) Шарик
      • 0
        s/Шарик/Дядя Фёдор/
  • +6
    Кстати, чтобы нарисовать идеальную прямую в винде, достаточно нажать Alt+Shift+Num Lock и включится управление указателем мыши с клавиатуры. Стрелочки это направления движения мышки, клавиша Insert(0) зажать клавишу мыши, del(.) отжать клавишу мыши.
    • 0
      Спасибо, раньше и не знал, что такое существует.
  • +2
    Эти ваши шарнирные конструкции выглядят так, что я сегодня всю ночь буду мучаться кошмарами :-(
  • +1
    Зрелище завораживает =) Прекрасная статья, которых давно не было на хабре. Единственное, даже при простых линиях механизм слишком сложен. Интересно, как это можно оптимизировать
  • +4
    Поясните, пожалуйста, что делается в этом фрагменте кода:

    this.O=[(this.Q[0]+this.R[0])/2,(this.Q[1]+this.R[1])/2];
    var PO=Math.sqrt(Math.pow(this.O[0]-this.P[0],2)+Math.pow(this.O[1]-this.P[1],2));
    var rb=0.6*a;
    var OT=Math.sqrt(rb*rb-PO*PO);
    var vertical=[this.S[1]-this.P[1],-this.S[0]+this.P[0]]
    var verticalLength=Math.sqrt(vertical[0]*vertical[0]+vertical[1]*vertical[1]);
    var eVertical=[vertical[0]/verticalLength,vertical[1]/verticalLength];
    this.T=[this.O[0]+eVertical[0]*OT,this.O[1]+eVertical[1]*OT];
    


    Поскольку из теории видно, что O — за пределами антипараллелограмма, а тут — будто она посередине между R и Q
    • +4
      Какой вы внимательный читатель)
      Просто в проге заместо точки 0 выступает точка Т:
      this.T=[this.O[0]+eVertical[0]*OT,this.O[1]+eVertical[1]*O;
      • +1
        Я так и попытался себе это представить :) но не могли бы вы еще технически пояснить, что есть 0,6 * а что такое vertical и eVertical (угловой коэффициент?)
        • +1
          Я знаю, что у программистов это плохой тон писать числа в теле программы) Но я не удержался)
          Если мне не изменяет память, 0.6 — это параметр надстройки на антипараллелограмм. Его в разумных пределах можно изменять.
          • +3
            Надстройки? Вероятно, следует прочесть какой-то из научных материалов, ссылки на которые вы давали?
            • +2
              Да. Надо прочесть доказательство)
              • 0
                К своему стыду, ни в обеих пдфках (дипломной работе и основном доказательстве), ни на странице не нашел упоминаний о «параметре надстройки» (о самой надстройке — нашел). Можете показать, что именно я упускаю?
                • +2
                  Если Вы в моем доказательстве посмотрите на правую часть этой картинки:
                  image
                  То увидите антипараллелограмм с красненькой «надстройкой», которая выполняет одну единственную функцию — не дасть антипараллелограмму вывернуться в параллелограмм. Дело в том, что точку О на рисунке можно выбрать в любом месте на серединном перпендикуляре к отрезку QR (или PS). И эта произвольность выбора точки О как-раз и контролируется коэффициентом в программе, который взял за 0.6.
                  Можно было его взять любым (в разумных пределах)
  • +6
    вот эту не подделает 229955.livejournal.com/pics/catalog/457/284
    • 0
      Это просто кто-то ручку расписывал. А настоящая подпись правее :)
  • +6
    Сделайте закрепленные шарниры визуально отличимыми от незакрепленных, пожалуйста.
  • +4
    Круто! Теперь я понял, что моя подпись имеет более высокую степень защиты, я один раз отрываю ручку от бумаги) Хотя с такими идеями скоро нужно будет вводить правила и уровни безопасности личной подписи. Вот так вот в недалёком будущем расписался на электронном бланке паспорта при получении онного, а тут из динамика: «Блюм, ваша подпись ненадёжна»)
    • 0
      Подпись определяет вас не столько по своей форме, сколько по манере её писать.
  • 0
    Осталось прикрутить 2 сервопривода и ручку))
  • +3
    Если кому хочется посмотреть на всякие клевые вещи, которые можно сделать с помощью шарнирных механизмов, то можно заглянуть сюда: www.etudes.ru/ru/
    • 0
      Огромное человеческое спасибо! Сколько лет пользуюсь штангенциркулемЮ но никогда не знал обоснования нониуса!
    • 0
      есть еще хороший сайт tcheb.ru
      • 0
        Ага. Приятно, что знаете! Одна хорошая команда все это хозяйство делает.
        • 0
          Как я понял, вы — часть этой команды? Спасибо вам за работу.
  • 0
    Очень сильно. Но тачскрин подпись программа не ест. А ведь пальцем на экране расписываться так естественно.
  • 0
    Плюсую за интересную работу.
    Мою подпись подделать не смог :)
    Сделал несколько попыток, разного размера. Не может.
    • 0
      Вероятно просто не хватает аппроксимации в 99, если, конечно, вы её не забыли выставить в 99
      • 0
        забыл :) ближе к 80 уже похоже
  • 0
    Выглядит жутко. Но впечатляет. Я бы добавил какое-нибудь сглаживание, чтобы простые фигуры рисовать с помощью более простых конструкций. Хотя не знаю, насколько это реализуемо.
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Интересно, почему даже для простой прямой линии (даже для точки) генерируется сложная система шарниров, хотя должна быть такая, как на 4-м рисунке в статье.
    • 0
      К сожалению, универсальный алгоритм устроен так. Конечно, можно было бы отдельно для прямой просто построить шарнир Липкина-Посселье, но я решил так не делать.
  • 0
    Хабра-эффекта на вашем сайте не боитесь?
    • +1
      уже испытал) Пришлось срочно делать зеркало на университетском сервере.
  • +1
    Круто! А сможет ваша программа нарисовать логотип Хабра? Там внутри будет мешанина из накладывающихся линий, до какого-то предела я думаю сможет, а потом будет каша из сплошного цвета.
  • +1
    В демо линии механизма накладываются друг на друга, а если в реальности создавать механизм, как реализовать, чтобы физические сочленения шарниров не встречались друг с другом, может «многоэтажность» надо делать?
    • 0
      Ага. Многоэтажность — отличное решение.
  • +1
    Это охренеть как круто!
    хочу такую штуку живьем увидеть.
    Нужно еще сделать, чтобы в 3d ее можно было смотреть, с разных ракурсов.
  • 0
    Всегда мучался вопросом глядя на различные механизмы и траектории движения деталей: Решение было заранее просчитано или это плод проб и ошибок?
    Получил ответ. СПАСИБО!
  • –1
    Чувак, я смотрю через две недели наступит четырехлетняя годовщина дня, когда ты чихнул.
    Готовишься к празднованию? Это же будет как раз накануне конца света!
  • 0
    Судя по тому, что при «аппроксимации = 1», устройство явно сложнее того, что на гифке в посте, получаемые механизмы можно еще на порядки упрощать
    • 0
      Для прямой — согласен. Но для аппроксимации выше чем 1, не уверен.
  • 0
    ах почему я до сих пор не придумал себе подпись
  • –6
    Нашел баг-не-баг. Недостаток алгоритма наверное. Если написать Hello вытягивая буквы (по оси x) и делать узкие петельки у «l», то рисуется совсем не то изображение.
    • +5
      Тяните аппроксимацию вправо.
      • +1
        Спасибо.
  • +2
    Спасибо за великолепно написанную статью!
    Несмотря на формулы и математические выдержки, читается на одном дыхании! В отличие от материалов по ссылкам :)

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

    И вопрос напоследок: а как добиться минимального количества звеньев? Даже прямая дается большим количеством при аппроксимировании 1.
    • 0
      Спасибо большое. Там слева есть ползунок «approximation». Надо его подвигать.
      • 0
        Извините. Сначала не понял вопроса. Дело в том, что общий алгоритм для степени аппроксимации n=1 не дает
        шарнир липкина-посселье. Я решил, что честнее будет оставить то, что дает общий алгоритм. Тем более, для случаев n>1
        я не вижу никакого обозримого способа упростить шарниры.
  • 0
    Не я все понимаю, но почему бы не оптимизировать алгоритм?
    image
    Порезать на куски и апроксимировать не?
    Аппроксимация на максимуме
    • 0
      на изображении 3! (sic) прямые нарисованные нампадом
    • 0
      Если порезать на куски то хватит тупых сплайнов или кривых безье.
      А подобрать конфигурацию отрезков можно с помощью ГА,
      • 0
        Тогда смысл аппроксимации в данном примере?
        • 0
          just4fun видимо.
          Но для реального решения можно сделать и проще и эффективнее.
          • 0
            Два пива этому девелоперу!
    • 0
      линию можно порезать на куски. А вот создать один общий шарнир для всех кусков — непонятно как.
  • +1
    Ух, спасибо. Всегда хотел знать как высчитывается хитрая траектория рычажных механизмов. (Например того адского механизма который ОДНИМ моторчиком в видаке Электроника ВМЦ8220 делает почти все. От заправки ленты в разные позиции, до выброса и загрузки кассеты).
  • 0
    Класс! Реализация выше всех похвал!
  • 0
    Даа… простейший механизм XY, типа плоттера не так впечатляет… однако делает то же самое ;-)

    Заменить 'рваные моменты' на идеальное вращение ценой тысяч рачагов??.. практического смысла в этом конечно — никакого, кроме доказательсятва — возможности.
  • +2
    Шарнирный механизм рисует мою подпись красивее, чем я.
  • +2
    Удивительной красоты пост, математик во мне ликует!
    Хочется придти домой и перечитать, разобравшись со всеми доказательствами и нюансами.
    Автор, спасибо за доставленное эстетическое удовольствие!
    • 0
      Спасибо, мне очень приятно)
  • 0
    Признаться, я потратил много сил на оптимизацию, чтобы ничего не тормозило на слабых компах, но, скажу честно, особых успехов не достиг.


    Спасибо, вы постарались на славу. На моем стареньком ноуте (Pentium-M 740, 512Mb, Firefox 17) рисует исключительно плавно, в отличие от многих других вебприложений.
  • +1
    Судорожно рисует логотип Хабрахабр ))

  • 0
    Слабые стороны данной реализации:
    * не справляется с острыми углами, аппроксимируя их в гладкие петли.
    * может развернуть петлю в противоположную сторону, что совсем не то, чего хотелось бы.
    * простым «прямым» (гладким) участкам уделяется много внимания, получается очень детализированный механизм для простого, который в итоге строит не сглаженный длинный штрих, а очень ломанный (здесь уже выше приводили примеры), в то время как сложные участки с завитками — слишком обделены вниманием.

    Но вообще, отличная вещь как старт для разработок, за что отдельное спасибо.
    Единственное, не нашёл ни одного упоминания слова «лицензия».
    • +1
      Про лицензию: официально разрешаю всем делать все что угодно с моим кодом, хоть на стенку туалета вешайте.

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