![](https://habrastorage.org/files/bf5/e25/667/bf5e256673ca49b591a1b8f54e39d39a.png)
Перевод поста Виталия Каурова "Automating xkcd Diagrams: Transforming Serious to Funny".
Скачать файл, содержащий текст статьи, интерактивные модели и весь код, приведенный в статье, можно здесь.
Выражаю огромную благодарность Кириллу Гузенко за помощь в переводе.
Утром в понедельник я наткнулся на интересный вопрос, опубликованный в Mathematica Stack Exchange, с нехитрым заголовком — "создание графиков в xkcd-стиле". Из-за популярности веб-комиксов xkcd Рэндалла Манро (Randall Munroe), я ожидал, что люди добавят себе несколько закладок этой страницы и с десяток up-vote. Тогда я ещё не знал, как всё обернётся. Сложно предсказать вирусность какого-то мема, однако если удалось создать такой, то весьма здорово наблюдать, как растёт его популярность и как он распространяется в интернете. Через два дня этот пост имел уже более 100 тысяч просмотров, двести up-vote и 150 закладок; стали возникать ответы и схожие посты в других разделах Stack Exchange, в Twitter разразился небольшой ураган по этому поводу, появлялись обсуждения в Hacker News и reddit. Тут я приведу оригинал поста Amatya с примером изображения в xkcd-стиле:
«Я получил электронное письмо, на которое я захотел ответить с графиком в xkcd-стиле, но я не мог справиться с этим. Всё, что я рисовал, выглядело как надо, однако я не мог придумать такой команды для Plot Legends, чтобы сделать фрагменты текста плавающими. Может, есть какие-то идеи, как можно было бы создать графики в xkcd-стиле? Когда всё выглядит рисованным от руки и неточным. Думаю, рисование таких странных кривых в Mathematica должно быть трудным в реализации.»
![Walking back to my front door at night Walking back to my front door at night](https://habrastorage.org/getpro/habr/post_images/817/3e5/d74/8173e5d74415ed6205ac442f6e1b50ae.png)
Однако оказывается, что рисование таких кривых линий в Mathematica столь же легко, сколь и весело. Mathematica Stack Exchange — быстрорастущее сообщество, организованное в формате вопрос-ответ, которое развивается исключительно усилиями самих пользователей. Я был рад увидеть, что он привлёк столько внимания этим интригующим вопросом и получил так много красивых и продуманных ответов. Рекомендую посетить оригинальный пост, чтобы просмотреть все ответы. Здесь я приведу лишь одно из решений, которое привёл Саймон Вудс (Simon Woods), которое более или менее универсально и применимо ко всем типам графиков в Mathematica, и даже к изображениям.
Саймон начинал с задания шрифта, который встречается в комиксах xkcd ().
![](https://habrastorage.org/getpro/habr/post_images/989/e22/b6b/989e22b6b6e93e4fe2501b617a05b4d9.png)
Следующим шагом было задание такой функции, которая конвертировала бы выводимый шрифт в стилизованный под xkcd. Для заданной точки на графике и смещения для текста, с помощью сплайна обозначенные точки соединяются плавной кривой.
![](https://habrastorage.org/getpro/habr/post_images/45e/bfb/b07/45ebfbb07326d86e00820c47c8b921cd.png)
Теперь самое время задать правила, которые для некоторого графического объекта будут заменять стиль текста на определённый нами xkcd-стиль, а также менять стиль линий. Обратите внимание, как в шестой строчке кода заменяются линии на жирные чёрные, которые отрисовываются поверх изначальных, но несколько более широких белых линий. Это нужно для того, чтобы задать заметный промежуток на одной кривой при пересечении с другой – характерная черта нарисованных от руки карикатурных диаграмм.
![](https://habrastorage.org/getpro/habr/post_images/59d/80d/001/59d80d001a28f580979512ad5e6189ae.png)
Следующая функция применяет вышеприведённые правила и делает оси более толстыми.
![](https://habrastorage.org/getpro/habr/post_images/f9e/d23/6a6/f9ed236a682d06585c13a1a22131f7ad.png)
![](https://habrastorage.org/getpro/habr/post_images/b61/6f0/625/b616f06250f1f9b7e643bb3396a4c11c.png)
Наконец, пришло время для части, отвечающей за обработку изображений — на мой взгляд, самая инновационная и интересная часть решения Саймона. Причина — возможность работы независимо от остального кода и с произвольными изображениями, а не только с графикой Mathematica. Как мы увидим далее, это даёт нам возможность применить xkcd-стиль к любой диаграмме. Цель представленной ниже функции — слегка исказить линии на изображении, чтобы сымитировать неровность, которая получается из-за начертания от руки.
![](https://habrastorage.org/getpro/habr/post_images/3ab/1ee/e32/3ab1eee325c71034be9a7dd6219c1afa.png)
Сперва функция растеризует графику Mathematica, преобразуя её в изображение. Затем она создаёт два случайных изображения и сглаживает их посредством свёртки с гауссовым ядром. Случайно, но плавно меняющиеся значения каждого пикселя этих изображений являются основой для определения смещений пикселей в исходном изображении. Смещение пикселей задаётся функцией ImageTransformation. Самая последняя функция применяет xkcd-стили и искажает изображения.
![](https://habrastorage.org/getpro/habr/post_images/fb1/9cf/9cc/fb19cf9cc489bf83b76f25f25d9f23ac.png)
Давайте опробуем это на нескольких графиках. Вот первый пример, который приводит Саймон, показывая, как всё это работает вместе.
![](https://habrastorage.org/getpro/habr/post_images/313/70a/86d/31370a86df89cf75743ffa5d7452d090.png)
![](https://habrastorage.org/getpro/habr/post_images/791/8be/ad6/7918bead63e6873002db0e64d06c7f07.png)
И вот несколько других примеров 2D и 3D графики, которые мы получили, используя xkcdConvert, из самых разнообразных графических функций Mathematica. Следует заметить, что xkcdConvert может применяться как к названиям функций, так и к результатам работы графических функций. То есть можно сперва создать некоторую 3D графику, провращать её, приблизить, панорамировать и лишь затем, уже к тому, что получилось, применить xkcdConvert.
![](https://habrastorage.org/getpro/habr/post_images/200/c27/155/200c271552d5505b85a1cb9fa6e3638c.png)
Стоит отметить, что Джон Маклун (Jon McLoone) несколько лет назад писал в посте "Self-Description" об автоматизации создания изображений в xkcd-стиле. Там он показывал, как создавать диаграммы в xkcd-стиле и добавлять различные цвета. Теперь мы можем добавить «кривоватость», вызванную ручным написанием:
![](https://habrastorage.org/getpro/habr/post_images/ef9/a6e/665/ef9a6e665fcf0c8eb283ba82623425ed.png)
![](https://habrastorage.org/getpro/habr/post_images/ff5/0ba/47a/ff50ba47aa2d3f709b5343b22e2f5e73.png)
Полагаю, всё выглядит довольно-таки аутентично. Отличная работа, Саймон! Я настоятельно рекомендую посмотреть на примеры кода и другие решения, которые приведены в оригинальном посте. Обратите внимание, как функция xkcdConvert может применяться к изображению напрямую. Однако у нас отсутствует возможность заменить шрифты на «забавные», так как шрифты тоже находятся в растровом виде. Тем не менее, эффект получается довольно реалистичным.
У Ю-Сунга Чана (Yu-Sung Chang) была прекрасная идея для создания CDF-приложения, которое берёт изображение по ссылке и стилизует его под xkcd. Ниже мы используем идею, которая немного отличается от идеи Саймона. В нашем случае рандомизированная функция BSplineFunction служит ориентиром для вытеснения пикселей ImageTransformation. Так же добавляется возможность регулировать амплитуду и частоту. Попробуйте вставить ссылку на изображение графика и просто нажмите Enter. Если Вам захочется, Вы можете инвертировать цвета, а так же можно скопировать результат в буфер обмена, чтобы сохранить изображение на своём компьютере.
![](https://habrastorage.org/files/a0c/487/670/a0c4876709514850b520eb5a27120868.png)
(скачать CDF-манипулятор)
Возникает вопрос — как продукт, который используется профессионалами в различных отраслях и исследователями в своих научных работах может так эффективно решать столь необычные задачи, включая задачи в сфере искусства, креативных направлений и нестандартных подходов. Ответ — интеграция. В Mathematica представлен широкий набор технологий и алгоритмов, доступных «прямо из коробки». Они разработаны очень тщательно и последовательно, так что пользователи могут из них собирать свои программы как из деталек конструктора LEGO. Давайте посмотрим, какие области мы затронули: графика, правила и шаблоны, обработка изображений, импорт и экспорт, операции с сетью, динамика и интерактивность, создание интерфейсов, развёртывание и использование CDF. Так что я надеюсь, что наши читатели, когда в следующий раз будут работать в Mathematica, когда будут решать уравнения, строить графики — будут помнить, что практически безграничные возможности для импровизации могут увести их далеко от повседневных задач.
Примечание
Мало кто знает, что Wolfram|Alpha может выдавать свои результаты в xkcd-стиле. Для этого в начале запроса достаточно просто указать слово "handwritten"
Несколько примеров:
Запрос "handwritten habrahabr"
![](https://habrastorage.org/files/587/c8e/d82/587c8ed829c74e7abe9ec98e00183002.png)
Запрос "handwritten Runge-Kutta method, dy/dx = -2xy, y(0) = 2, from 1 to 3, h = .25"
![](https://habrastorage.org/files/ca3/e51/2f5/ca3e512f5a444276aa6031d7590dd357.png)
Запрос "handwritten radioactive elements"
![](https://habrastorage.org/files/aad/566/37c/aad56637ce134598881906f035ee0a51.png)