Поскольку гильоши использовались как средство защиты ценных бумаг от подделки, все, что связано с их использованием, было засекречено, и информацию приходится собирать по крупицам.
Само название происходит от фамилии французского инженера Гийо (Guillot), о котором не осталось никаких сведений. Не исключено, что это вообще чисто мифическая фигура.
Первоначально гильоши использовались для гравировки волнистых линий на корпусах часов, яйцах Фаберже и тому подобных предметах, на которых требуются строгие геометрические украшения. Выполнялись они некоторой разновидностью токарного станка, в которой резец не был жестко закреплен, а описывал фигуры вокруг крутящейся заготовки.
Примерно в середине XIX века кому-то пришла в голову идея приспособить такой станок для генерации сложных узоров на типографской пластинке. Скорее всего, это были американцы, поскольку на их деньгах гильоши появились раньше всего — на выпуске 1862 года, и очень быстро стали одним из главных элементов дизайна.
Постепенно их заимствовали почти все развитые страны — кроме Франции, которая придерживалась исключительно живописной манеры рисования банкнот, не отвлекаясь на механические штучки.
На российских деньгах гильоши первый раз были напечатаны в выпуске 1892 года.
Если рассматривать сами узоры на деньгах разных стран, то можно заметить, что, несмотря на общий принцип, они довольно сильно различаются. Отсюда можно сделать вывод, что каждый разрабатывал соответствующие станки самостоятельно. Заметна и корреляция — чем развитее страна, тем ее гильоши сделаны лучше. Для примера достаточно посмотреть на румынские деньги времен Чаушеску, где для гильошировочной машины, похоже, использовались детали от трактора.
Создание гильошей было сложным делом — настолько сложным, что этим занимались отдельные люди, имевшие особую профессию гильошировщика. По некоторым сведениям можно понять, что гильошировщики рисовали гильош по эскизу художника — это видно из приводимого примера наброска и готовой банкноты в 1 червонец 1926 года. Не удивлюсь, если они это делали путем механической подгонки деталей, а то и вообще перебирали машину заново.
Сейчас гильоши из моды вышли, поскольку они могут противостоять только рисованию денег руками — попробуй чернилами вычертить все эти мелкие кривые. При использовании оптического копирования они бесполезны — сканеру все равно, что считывать: узоры или портреты. Так что на современных банкнотах гильошей обычно уже нет или они скромно торчат где-нибудь в углу как дань традиции.
Вычислить алгоритм для рисования гильошей крайне сложно — хотя на вид они кажутся достаточно простыми. Во многих источниках пишут, что это всего лишь усложненная версия спирографа с несколькими колесами, но я в этом сильно сомневаюсь. Многоколесный спирограф несложно повторить на компьютере, но получающиеся узоры во-первых, нисколько гильоши не напоминают, а во-вторых, их невозможно подогнать к заранее заданным контурам.
Ясно, что гильош — это семейство синусоид, сдвинутых по фазе относительно друг друга, и искажающихся в зависимости от внешних контуров так, чтобы не переходить их границы. Это очевидно — но совсем не очевидно, как именно математически контуры на синусоиды влияют.
На самом деле принцип построения узоров довольно прост, но несколько странноват. Они считаются по точкам, причем простых алгебраических операций над тремя кривыми (внутренним, внешним контуром и синусоидой, стелящейся между ними) недостаточно — нужно еще решать уравнения, чтобы определить пересечение линии и кривой.
Собственно, в каждой точке мы ставим точку синусоиды, но каждый раз разной — как бы модулированной текущим состоянием ограничивающих контуров.
Как именно необходимые вычисления выполнялись на механических станках, выше моего понимания.
Итак, принцип рисования. Мы начнем с горизонтального гильоша, потому что он проще. Внимание на экран.
Зеленым цветом выделены контуры, ограничивающие наш гильош. Будем считать их нижним и верхним и рассчитаем значение точки гильоша в абсциссе t.
Прежде всего найдем точки PB и PT — точки контуров при t. Заодно высчитаем в этом месте векторы направления кривых.
Теперь найдем некую среднюю точку Mid между нижним и верхним контуром. Именно от нее будет отсчитываться рисование нашей красивой кривой. Мы можем взять просто точку, среднюю между PB и PT, а можем еще умножить ее на некий коэффициент 0..1, показывающий, в какой пропорции следует учитывать нижний и верхний контур. Тогда мы сможем чуть смещать гильош вверх-вниз между контурами, чтобы добиться более красивых фигур.
Высчитаем в этой точке вектор направления как средний между векторами в точках PB и PT. Найдем для него перпендикуляр.
Посчитаем значение самой обыкновенной синусоиды в точке t (в предположении, что она начинается в точке 0,0 и движется вдоль оси ординат вправо).
Теперь исказим эту синусоиду следующим образом: перенесем текущее значение ее аргумента (t,0) в точку Mid, ее осью X сделаем «средний вектор», а осью Y, соответственно, перпендикуляр к нему. Тогда ее текущая точка окажется в точке RP.
Осталось только смодулировать амплитуду этой синусоиды. Посчитаем расстояние Mid--IP, то есть расстояние от средней точки до первой точки пересечения перпендикуляра с контуром. Какой контур брать, верхний или нижний, мы определим по значению исходной синусоиды — находится она выше оси ординат или ниже. На рисунке изображен случай, когда значение эталонной синусоиды больше нуля и мы используем верхний контур.
Теперь масштабируем Mid--RP, считая расстояние Mid--IP единицей, и отложим это значение вдоль новой оси ординат, т.е. по перпендикуляру. Мы получим точку GP — она и будет искомой точкой гильоша.
Перейдем к программированию. Вот программа рисования горизонтального гильоша на языке Asymptote:
import graph;
import wave;
size(1000,1000);
xaxis(ticks=Ticks);
yaxis(ticks=Ticks);
defaultpen(2);
var zero = (0,0);
typedef pair pairf(real x);
///////////////////////////////////////////
// Единичный вектор, перпендикулярный к вектору (0,0)--v
pair orthogonal(pair v)
{
return unit((-v.y,v.x));
}
// Точка и направление кривой в точке с координатами x,path(x)
pair[] pt_and_dir(path p, real x)
{
var t = times(p,x)[0];
return new pair[]{point(p,t), dir(p,t)};
}
// Функция, рассчитывающая точку гильоша в точке с абсциссой t
pairf between(path top, path bottom, real topk=0.5, real phase, real omega)
{
return new pair(real t)
{
// Точка и направление верхнего и нижнего контура
var pdt = pt_and_dir(top,t);
var pdb = pt_and_dir(bottom,t);
// "Средняя" точка как смесь из верхней и нижней
var mid = topk*pdt[0] + (1-topk)*pdb[0];
// Выведем для наглядности среднюю точку
draw(mid,gray);
// Вектор, перпендикулярный смеси направлений верхней и нижней точки
var ort = orthogonal(topk*pdt[1] + (1-topk)*pdb[1]);
// Точка на обычной синусоиде, которую мы сейчас будем модулировать
var f = sin(phase+omega*t);
// Вектор, в сторону которого модуляция отклонит точку
var rp = rotate(degrees(atan2(ort.y,ort.x)-pi/2),zero) * (0,f);
// Рассчитываем точку пересечения перпендикулярного вектора с одним из контуров
// Для этого узнаём все точки пересечения и берем из них ближайшую
var ipath = rp.y >= 0 ? top : bottom;
var inter = intersections(ipath,mid,mid+ort);
var interp = sequence(new pair(int i) {return point(ipath,inter[i]); }, inter.length);
interp = sort(interp, new bool(pair a, pair b) {return abs(mid.x-a.x) < abs(mid.x-b.x); });
var ip = interp[0];
// Узнаем расстояние от "средней точки" до точки пересечения перпендикулярного вектора с контуром
var r = sqrt((mid.x-ip.x)*(mid.x-ip.x)+(mid.y-ip.y)*(mid.y-ip.y));
// Модулируем синусоиду
return mid+r*rp;
};
}
// Рисуем гильош несколько раз со сдвигом
void repeat(int n, path top, path bottom, real topk, real freq)
{
var step = 2pi/n;
for (var i: sequence(0,n))
{
draw(graph(between(top,bottom, topk, i*step, freq), 0,8, 500));
}
}
// Верхний контур - просто что-то типа синусоиды
path top = shift(0,0.3)*(4*make_wave(1.4, (+1,+0.7),(+1,-0.7) ));
// Нижний - прямая
path bottom = (0,0)--(8,0);
draw(top, blue);
draw(bottom, blue);
// укладываем между ними 9 "синусоид" с частотой 11, проходящих точно посередине между верхним и нижним контуром
repeat(9, top, bottom, 0.5, 11);
А вот результат ее работы. Изящно.
С круговыми гильошами — как раз теми, что обычно фигурируют на деньгах — дело усложняется. Принцип остается тем же, но…
1. Вместо декартовых координат приходится работать в полярных
2. Кривые становятся капризными и начинают себя плохо вести. При более-менее сложных контурах в некоторых точках возникает ситуация, когда перпендикуляр вовсе не пересекается с нужным контуром. Очевидно, в таких случаях и требуется многолетний опыт гильошировщика.
Итак, программа. Обратите внимание, что в ней контуры по аналогии с предыдущей программой называются верхним и нижним, хотя реально они внешние и внутренние.
import graph;
import wave;
size(1000,1000);
xaxis(ticks=Ticks);
yaxis(ticks=Ticks);
defaultpen(5);
var zero = (0,0);
typedef pair pairf(real x);
typedef pair[] pairaf(real t);
///////////////////////////////////////////
// Определение перпендикулярного вектора
pair orthogonal(pair v)
{
return unit((-v.y,v.x));
}
// Пересчет полярных координат в декартовые
pair cart(real a, real r)
{
return (r*cos(a), r*sin(a));
}
// Нормализованный угол по вектору-направлению
real atan2p(pair v)
{
var a = atan2(v.y,v.x);
return a<0 ? a+2pi : a;
}
// Расстояние между двумя точками
real distance(pair a, pair b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
// Точка и вектор направления на пути p при полярном угле a
pair[] pt_and_dir(path p, real a)
{
var ii = intersections(p,zero--cart(a,100));
if (ii.length==0)
{
write(p);
write(a);
}
var t = ii[0];
return new pair[]{point(p,t[0]), dir(p,t[0])};
}
// Вычисление точек гильоша, если имеется функция midpoint, рассчитывающая координаты и направление в средней точке
pairf between(path top, path bottom, pairaf midpoint, real phase, real omega)
{
return new pair(real t)
{
var b = midpoint(t);
var mid = b[0];
draw(mid,green);
var mid_dir = b[1];
var f = sin(phase+omega*t);
var angle = (degrees(atan2p(mid_dir))+180) % 360;
var rp = rotate(angle,zero) * (0,f);
//На какой контур смотрит вектор нашей точки синусоиды - на верхний или нижний?
var ipath = distance(mid+rp,zero) > distance(mid,zero) ? top : bottom;
// Найдем точки пересечения перпендикуляра с контуром
var inter = intersections(ipath,mid,mid+rp);
// Вот тут-то и засада. Пересечений с контуром может вообще не быть. Выводим тогда линию противного цвета,
// чтобы это было сразу заметно
if (inter.length==0)
{
draw(mid--mid+rp,magenta,Arrow);
return mid;
}
// Отсортируем точки пересечения и найдем самую ближнюю
var interp = sequence(new pair(int i) {return point(ipath,inter[i]); }, inter.length);
interp = sort(interp, new bool(pair a, pair b) {return distance(mid,a) < distance(mid,b); });
var ip = interp[0];
var r = distance(mid,ip);
return mid + r*rp;
};
}
// Вычисление точек гильоша, если задан средний путь
pairf between(path top, path bottom, path base, real phase, real omega)
{
pairaf mf = new pair[](real t) { return pt_and_dir(base, t); };
return between(top, bottom, mf, phase, omega);
}
// Вычисление точек гильоша, если дан коэффициент смешивания верхнего и нижнего контуров
pairf between(path top, path bottom, real topk=0.5, real phase, real omega)
{
pairaf midpoint = new pair[](real t)
{
var pdt = pt_and_dir(top,t);
var pdb = pt_and_dir(bottom,t);
var mid = topk*pdt[0] + (1-topk)*pdb[0];
var mid_dir = topk*pdt[1] + (1-topk)*pdb[1];
return new pair[]{mid, mid_dir};
};
return between(top, bottom, midpoint, phase, omega);
}
// Рисование гильоша с вычислением средней линии (как в программе с горизонтальным гильошем)
void repeat(int n, path top, path bottom, real topk, real freq)
{
var step = 2pi/n;
for (var i: sequence(0,n-1))
{
draw(graph(between(top,bottom, topk, i*step, freq), 0, 2pi, 500));
}
}
// Вариант - средняя линия не вычисляется, а задается отдельным путем
void repeat(int n, path top, path bottom, path base, real freq)
{
var step = 2pi/n;
for (var i: sequence(0,n-1))
{
draw(graph(between(top,bottom,base, i*step, freq), 0, 2pi, 500));
}
}
// Контуры - внешний и внутренний. Чтобы не возиться с вычислением их координат, я просто обвел их в векторном редакторе,
// сохранил как SVG и извлек из текста описание пути
path top = (458.43,237.715)..controls (468.922,264.461) and (481.563,290.133)..(466.797,322.145)
..controls (438.688,358.184) and (392.762,345.094)..(362.438,351.945)
..controls (354.488,353.742) and (350.508,354.398)..(342.07,358.234)
..controls (338.023,360.074) and (333.797,358.609)..(329.125,358.598)
..controls (324.457,358.582) and (319.348,360.02)..(315.824,363.094)
..controls (306.16,371.52) and (294.707,387.746)..(278.176,400.949)
..controls (261.645,414.152) and (250.875,417.965)..(236.914,417.996)
..controls (222.957,418.023) and (213.074,414.152)..(196.543,400.949)
..controls (180.012,387.746) and (168.559,371.52)..(158.895,363.094)
..controls (155.371,360.02) and (150.262,358.582)..(145.594,358.598)
..controls (140.922,358.609) and (136.695,360.074)..(132.648,358.234)
..controls (124.211,354.398) and (120.23,353.742)..(112.281,351.945)
..controls (81.957,345.094) and (36.0313,358.184)..(7.92188,322.145)
..controls (-6.84375,290.133) and (5.79688,264.461)..(16.2891,237.715)
..controls (19.1992,230.289) and (11.7227,218.836)..(11.7227,209.773)
..controls (11.7227,200.711) and (19.1992,188.906)..(16.2891,181.48)
..controls (5.79688,154.734) and (-6.84375,129.063)..(7.92188,97.0508)
..controls (36.0313,61.0078) and (81.957,74.0977)..(112.281,67.2461)
..controls (120.23,65.4531) and (124.211,64.7969)..(132.648,60.9609)
..controls (136.695,59.1211) and (140.922,60.582)..(145.594,60.5977)
..controls (150.262,60.6094) and (155.371,59.1719)..(158.895,56.1016)
..controls (168.559,47.6719) and (180.012,31.4492)..(196.543,18.2461)
..controls (213.074,5.03906) and (222.957,1.16797)..(236.914,1.19922)
..controls (250.875,1.22656) and (261.645,5.03906)..(278.176,18.2461)
..controls (294.707,31.4492) and (306.16,47.6719)..(315.824,56.1016)
..controls (319.348,59.1719) and (324.457,60.6094)..(329.125,60.5977)
..controls (333.797,60.582) and (338.023,59.1211)..(342.07,60.9609)
..controls (350.508,64.7969) and (354.488,65.4531)..(362.438,67.2461)
..controls (392.762,74.0977) and (438.688,61.0078)..(466.797,97.0508)
..controls (481.563,129.063) and (468.922,154.734)..(458.43,181.48)
..controls (455.52,188.906) and (462.996,200.238)..(463.055,209.359)
..controls (463.113,218.48) and (455.52,230.289)..(458.43,237.715)
--cycle;
path bottom = (435.121,232.246)..controls (424.465,250.848) and (436.73,269.879)..(418,294.242)
..controls (399.266,318.602) and (368.48,321.363)..(355.004,331.102)
..controls (341.531,340.84) and (349.316,349.461)..(338.301,353.699)
..controls (327.289,357.934) and (311.055,338.211)..(297.848,342.762)
..controls (277.797,349.668) and (257.313,362.477)..(235.926,362.551)
..controls (214.543,362.629) and (196.012,350.156)..(175.961,343.25)
..controls (162.75,338.699) and (146.52,358.422)..(135.504,354.188)
..controls (124.492,349.949) and (132.277,341.328)..(118.805,331.59)
..controls (105.328,321.852) and (74.5391,319.09)..(55.8086,294.73)
..controls (37.0742,270.367) and (49.3438,251.336)..(38.6875,232.734)
..controls (33.918,224.414) and (17.0078,213.824)..(17.0078,209.363)
..controls (17.0078,204.902) and (33.9258,194.051)..(38.6953,185.727)
..controls (49.3555,167.129) and (37.082,148.094)..(55.8242,123.734)
..controls (74.5625,99.375) and (105.359,96.6094)..(118.84,86.875)
..controls (132.32,77.1367) and (124.531,68.5117)..(135.547,64.2773)
..controls (146.566,60.043) and (162.805,79.7617)..(176.016,75.2148)
..controls (196.078,68.3086) and (214.613,55.832)..(236.008,55.9102)
..controls (257.398,55.9883) and (277.891,68.7969)..(297.953,75.7031)
..controls (311.164,80.2539) and (327.402,60.5313)..(338.418,64.7656)
..controls (349.438,69.0039) and (341.648,77.625)..(355.129,87.3633)
..controls (368.609,97.0977) and (399.406,99.8633)..(418.145,124.223)
..controls (436.887,148.586) and (424.613,167.617)..(435.273,186.219)
..controls (440.043,194.539) and (456.961,205.215)..(456.926,209.535)
..controls (456.887,213.859) and (439.891,223.926)..(435.121,232.246)
--cycle;
// Подгоняем под масштаб нашего рисунка
top = scale(1/10)*top;
bottom = scale(1/10)*bottom;
// И смещаем контуры из центра координат в левый верхний квадрант
var min = min(top);
var max = max(top);
top=shift(-(max.x-min.x)/2, -(max.y-min.y)/2)*top;
min = min(bottom);
max = max(bottom);
bottom=shift(-(max.x-min.x)/2-min.x, -(max.y-min.y)/2-min.y)*bottom;
draw(top, blue);
draw(bottom, blue);
// Пускаем 4 синусоиды
repeat(4, top, bottom, 0.5, 18);
Результат — нечто похожее на розетку с купона в 25 белорусских рублей 1992 года. Можно сделать еще похожей, если самому аккуратно нарисовать среднюю линию (см. второй рисунок).
Некоторые линии на нашем рисунке получились с зазубринами — это из-за недостатка точности вычислений. В какой-то степени их можно исправить, поставив в операторе draw расчет не 500, а 10000 точек.
Что можно еще придумать с гильошами?
Во-первых, если внимательно посмотреть на белорусскую версию, то заметно, что тамошние узоры еще меняют свою частоту — они становятся то гуще, то реже. Как учитывать частоту в моей программе — я так и не придумал.
Во-вторых, гильоши прямо-таки напрашиваются быть сохраненными в виде кривых Безье — они очень хорошо ими аппроксимируются. Но для этого надо понимать, как они себя ведут — где у них вершины, где точки перегиба. Вычислять это из набора точек как-то глупо, а как подойти к вопросу математически, например, посчитав производную, — непонятно.
Если у многоуважаемой публики есть на этот счет какие-то соображения, прошу делиться.
P.S. Рисунки в статье отмасштабированы, чтобы не портить общий вид страницы. Вы можете открыть их отдельно и рассмотреть с лучшим разрешением.
Комментарии (44)
Holix
12.07.2016 14:47Очень интересно. Очень давно (лет 20 назад) сталкивался с этими «завитушками» и даже пытался как-то их воспроизвести в CorelDraw, но не справился. :)
По поводу проецирования на сложные контуры. Мне кажется, что декартовы координаты можно спроецировать на плавную кривую, где вектор нормали будет у нас за ось Y, а смещение вдоль кривой X. Тогда можно нарисовать почти произвольные формы.
polar11beer
12.07.2016 15:56>> При использовании оптического копирования они бесполезны — сканеру все равно, что считывать: узоры или портреты.
Не согласен. Обычный бытовой сканер не воспроизведёт тонкие линии, на их месте будет сплошной фон.nikolay_karelin
12.07.2016 16:03+3Скорее так: у сканера или копира прямоугольная сетка сканирования, а линии в гильоше идут под очень странными углами, в результате при не очень высоком разрешении получаются искажения, которые очень хорошо заметны на копии или скане: меняется рисунок муара и подделку можно заметить даже при взгляде мельком на банкноту.
vvzvlad
12.07.2016 16:16+8А еще их часто можно отсканировать(найти сканер лучше или просто переснять хорошим макро-обьективом), но нельзя напечатать — во-первых, они очень тонкие(так как делаются штампом, а не обычной печатью), и бытовой принтер не может их воспроизвести, а во-вторых, состоят из одного цвета, который принтер попытается вопроизвести тремя в разных пропорциях, из-за чего на копии, при сильном увеличении, будут видны разноцветнеы точки, а не одна линия.
basnopisets
12.07.2016 17:29+1а если еще ирисный раскат использовать для печати гильоша то их вообще невозможно будет повторить. Поэтому автор погорячился с таким безапелляционным утверждением о бесполезности гильошей
gatoazul
12.07.2016 21:14Вижу, что на всех новых банкнотах их практически нигде нет.
nikolay_karelin
13.07.2016 10:43А какие банктноты вы смотрели?
gatoazul
13.07.2016 11:20Я просматриваю новые банкноты всех основных стран мира.
Можно взять СНГ для примера.
Россия — гильоши только в розетке с номиналом на обратной стороне. Были еще на 1000 слева, затерты и заменены голограммой.
Украина — некое подобие на 10 грн, на розетке с номиналом слева.
Белоруссия, выпуск 2009 года — нет
Казахстан — нет.
Литва, Латвия, Эстония — нет.
Грузия — нет
Армения — нетgaki
13.07.2016 11:46Посмотрел щас нестарую на вид тысячейеновую банкноту — она, по-моему, этими гильошами покрыта абсолютно вся. Не знаю, правда, что это доказывает.
gatoazul
13.07.2016 14:23Что Япония придерживается традиций — не более того. Новый европейский стиль, начатый немецкой маркой выпуска 1992 года, сильно отличается.
Zenitchik
14.07.2016 19:18Достал из кармана 100 RUR. Гильоши вокруг номинала на обороте в правом верхнем углу.
На 1000 RUR — аналогично. Купюра новая.
А вот на 5000 RUR — гильошей нигде не нашёл, только тень цифр номинала в левом верхнем углу зарисована чем-то подобным, но невооружённым глазом я не разглядел, гильоши это или просто сетка.
gatoazul
12.07.2016 21:15+1Он и микропечать не воспроизведет, и тонкие штрихи на гравированном портрете. Так что в гильошах тут нет ничего уникального.
keslo
12.07.2016 16:10+2Спасибо за статью.
Название статьи из одного слова — прям в глаза бросилось!
У меня на главной Я стоит виджет Хабра. И однословный заголовок очень сильно в нем выделился. Надо взять на заметку :-)Acuna
12.07.2016 19:17+2Соглашусь, только из-за этого и открыл сию статью и прочитал просто с огромным интересом! Только к сожалению если все авторы прочувствую эффективность односложных заголовков — то такими вскоре станут все заголовки. Так что тут палка о двух концах, если честно…
ArkturTierry
12.07.2016 16:48+5По поводу защиты -гильоши применяются до сих пор. Технически на полиграфических машинах их воспроизвести не очень-то и просто, во-первых потому что при растрировании векторной графики с таким сложным рисунком RIP (rast image processor) нагружается очень сильно, вплоть до невозможности выполнения задачи.
Во-вторых, гильошь применяется для защиты не сам по себе а совместно с Орловской печатью ru.wikipedia.org/wiki/%D0%9E%D1%80%D0%BB%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F_%D0%BF%D0%B5%D1%87%D0%B0%D1%82%D1%8C, когда краски из разных секций совмещаются на одном печатном цилиндре
и ирисовый раскат forum.print-forum.ru/showthread.php?t=571276 когда разные краски в красочный аппарат добавляются в пределах одной красочной секции.
Тогда (как видно в т.ч. на приведенных в статье примерах) удается идеально совместить линии разного цвета и получить красивый переход, без разрыва линии.
Повторить цифровыми методами эти приемы или невозможно или крайне трудно (и всё равно отличимо на хорошем увеличении).
anandr
12.07.2016 18:34+3В принципе, кривые для гильош можно вместить между внутренним и внешним контурами в полярных координатах используя простой алгоритм. Суть в том, что сначала считаются массивы точек для внешнего и внутреннего контуров и их «средняя линия» для кажого значения полярного угла. Затем для этих же значений полярного угла рассчитываются точки внутренних кривых от внутреннего к внешнему контурам пропорционально значениям их «косинусов» учитывая сдвиг по фазе для каждой кривой.
Выходит что-то типа этого (анимированная гифка здесь: https://habrastorage.org/getpro/habr/comment_images/b01/20f/451/b0120f451e80d9722272e7091d0de7fa.gif):
impetus
12.07.2016 20:39+3А можно эту гифку закольцевать? Случайно увидел, что она анимированная оказывается
anandr
13.07.2016 11:12Гммм, действительно, только один раз проигрывается почему-то (делал ее в Matlab используя imwrite, в котором 'LoopCount'=inf по умолчанию; но если поставить 'LoopCount'=65535 то вроде проигрываетсь много раз).
Вот полная анимация (я не нашел как удалить картинку из первого комментария):
impetus
12.07.2016 20:21+1Гильоши хороши по металлу! — там из-за того, что эта сложная кривая чертится резцом с гранями — узор потом имеет очень сложные отражения от этих граней, как бы «играет». Делал свободнокачающимся на оси гравёром с 3d-фрезера: вид — фантастика, но очень медленно, штучное по сути изделие получается (чем оно, собственно, и было — ювелирка), и сфотографировать практически без шансов — сплошные блики, нефокус и т.п. а приличной зеркалки с макрообъективом, штативом и лайт-боксом под рукой не было. Потом поверх прозрачная эмаль.
gatoazul
12.07.2016 21:17+1Прямо такие и делали? А можете описать хотя бы примерно сам станок?
impetus
12.07.2016 21:39+1не, я на обычный настольный 3d-фрезер — в шпиндель перо-гравёр (дорогое сцуко), вращение у шпинделя отключаем — пусть самоустанавливается «по потоку»), картинка какой-то простой программы (кажется называлась ещё «розетта», но сейчас из-за космостанции и обучалки языку её не найти), потом долгое шаманство с g-кодами, с учётом особенностей самого фрезера, что бы кривая была гладкая.
в качестве детали — заранее отлитую по форме, полированную, отожжённую пластинку из серебра (она потом в оправку и заливается эмалью).
Это всё в условиях ювелирной мастерской.
Сложно, геморрно, дорого и не тиражируемо в итоге получается, много проще вставить камушек и не париться, тем более что они сейчас в общем-то даром http://www.sapphire.ru/vcd-344/catalog.html (и далее внутрь каталога. там внутри много больше, чем снаружи кажется).
aczkasow
14.07.2016 12:27+1Такие узоры очень популярны дорогих механических часах. Если интересно как работает станок и мастер, то можете посмотреть на ютубе видео Art of Guilloche.
BoBRoID
13.07.2016 11:06по поводу утверждения автора о неактуальности гильош на ценных бумагах википедия говорит «Согласно существующим нормативам, гильоширные элементы должны занимать не менее 70 % площади ценных бумаг»
открыл кошелёк, достал купюру (2 грн), убедился что википедия не врётgatoazul
13.07.2016 11:07Стесняюсь спросить, где же там 70% гильошей? Или вы тангирную сетку гильошами называете?
claygod
13.07.2016 13:59Читаю на купюре в 1 червонец 1926 года: «1 червонец содержит 7.74гр. чистого золота». Эх…
sim31r
16.07.2016 12:40Золото не идеал меры ценности, в цене менялось в 10 раз с 1970 года
Сейчас еще подводные месторождения освоят и цена вниз пойдет, или повысится спрос и пойдет вверх.
sim31r
16.07.2016 14:39+1В принципе, кривые для гильош можно вместить между внутренним и внешним контурами в полярных координатах используя простой алгоритм.
Вариант еще проще. Просто синусоида в полярных координатах, радиус меняется по синусоиде, круг немного модифицирован в эллипс
то же самое за 3 оборота, одна линия, плавно увеличивается фаза до 2Pi и линия получается без разрывов
Тут 10 оборотов линии вокруг центральной точки.
faza:=faza+(2*pi/step)/n;
r:=sin(10*i*2*pi/step+faza);
r:=r*40;
r:=r+150;
sim31r
16.07.2016 15:08+280 цикловsim31r
16.07.2016 15:36+2Модифицировал немного синусоиду деформацией по ходу рисования:
Заголовок спойлераZenitchik
16.07.2016 18:12А закон деформации какой?
sim31r
16.07.2016 20:40+1Перо вращается вокруг центральной осевой линии, 10 оборотов на «лепесток», радиус 5 пикселей, малый радиус приводит к едва заметным искажениям, которые интересно проявляют в структуре из множества линий, появляется эффект 3D неожиданно. Я планировал только более витиеватую структуру узора.
Тут фигура Лиссажу более сложная
sim31r
16.07.2016 15:51+3Не садитесь рисовать эти узоры, это как наркотическая зависимость ))
Заменили центральный эллипс на фигуру Лиссажу
sim31r
16.07.2016 23:33+1Чтобы сжимать картинки с тонкими линиями хорошо подходит gif, png. Но gif на 1000 кадров создавать как-то сложно, стандартные видео кодеки жмут не корректно
Жаль не стал стандартом формат APNG из этой статьи. Или raw видео сжатое zip/rar алгоритмом, тоже что-то сравнимое выдает.
anandr
20.07.2016 11:34Да, это самый простой вариант. Но этим способом можно получить только те кривые, у которых внутренняя и внешняя огибающие эллипсы. Если же огибающие сложной формы, то для таких гильош математика будет сложнее.
Например, на этом рисунке
внутренняя огибающая в полярных координатах имеет форму синусоиды и частоту 6 (r ~ sin(6*phi)), а внешняя — 12. Пространство между ними заполнено 15 синусоидами с частотой 20 по вышеописанному алгоритму.
Scratch
Вы мне напомнили о славных временах когда все пытались поломать программу Cerber, которая эти самые Гильоши рисует. Славно, что технологии не стоят на месте )
basnopisets
да, была такая) тоже пытались, а то стоила она каких-то диких денег
Sykoku
Есть Rozetta. Бесплатная.
gatoazul
Она рисует не настоящие гильоши, а просто симметричные розетки.
Sykoku
Ну, это тоже гильош. Арка входа в храм Сан-Сальваторе ин Лауро, Рим. Хотя там и розетки есть (от фр. rosette, буквально «розочка») — мотив орнамента в виде лепестков распустившегося цветка или нескольких листьев, одинаковых по форме, расположенных симметрично и радиально расходящихся из сердцевины, аналогично ботанической розетке.