• Авторизация


Рекурсия, Эффект Дросте. Часть 1 22-03-2012 15:23 к комментариям - к полной версии - понравилось!

Это цитата сообщения Natariel Оригинальное сообщение

[420x425]

Картинная галерея Эшера

Всем салют! Многие из нас любят, и многих из нас привлекает, все необычное и удивительное. Эффект Дросте относится именно к таким чудесам пречудесным. Про этот эффект не слышал только ленивый, о нем еще с 1914 года активно шепчутся.. А несколько лет назад появились первые умельцы, которые поставили эту технику на автоматический процесс — упорные программисты не стоят на месте. Теперь желающим не нужно тратить часы на вычисления и громоздкие коллажирования. Это как работа с современным фотоаппаратом: он все сделает за вас (упростив подготовку в техническом плане), вам остается только творчество — так и здесь:

[700x450]

Так что же такое рекурсия и что такое эффект Дросте? Если кратко, то рекурсия — это самовоспроизведение чего либо или его части в самом себе, на подобии эха, только с сохранением всех свойств (будь то формула программирования, литературная забава или изображение…). Самый простой способ добиться этого эффекта — это поставить два зеркала друг напротив друга… или почитать об этом довольно занимательную статью (ай) (цвай, драй). Кто же еще, кроме сладострастной шоколадной марки Дросте, был виной тому, что я пишу эти строки? — Эшер!!!.. О этот Эшер, беспощадно и бесповоротно трахнувший мои невинные детские мозги, своими импартовскими гравюрами! О его подстрекатели — Пэнроуз и мерзкий популяризатор, матеМаг Гарднер…)):

[700x450]

Часто бывает так, что вроде "удивительное рядом, но оно запрещено", только не сегодня друзья, только не на моей смене — можем же мы позволить себе прикоснуться к загадочному и поколдовать со своими фотографиями? Выбирайте сами: или вы соглашаетесь со мной и разрешаете себе этот каприз… или говорите — "Не вопрос Андрей, конечно же да!". Решать только вам — это, до кончиков аксонов и дендритов, ваш самостоятельный выборgrin

Я постараюсь не перегружать материал, хоть объема и будет немало (поверьте, времени было потрачено до неприличия больше). Это ведь не просто урок — это подобие облегченной статьи-урока, со всеми вытекающими. Да, нужный материал вполне легко вместить на одну страницу и отпустить вас в кручения-верчения. Только позвольте уж провести вас по всей тропе лабиринта, чтобы вы прониклись техникой в большей мере. Я не стал все впихивать в одну тему, поэтому в этой части мы рассмотрим только базовую составляющую, необходимую для получения эффекта, после чего вы сможете пожинать плоды создания начальных, но уже "дроздирующих" картинок. А в следующих темах будут рассмотрены некоторые хитрости, премудрости с нюансами и более прикладной материал:

[700x450]

Что я сейчас скажу, так это то, что работу будем выполнять в Гимпе + придется скачать для него один весьма полезный плагин (все бесплатно)… Сразу обозначу тот факт, что существует возможность прикрутить существующий фильтр Дросте к CS4 и AE. Но обо всем по порядку.

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

Несколько же теплых зим ранее, после просмотра увлекательного ролика с рекурсией, я и сам искал ответы на вопрос: — «как сделать такую картинку?» — уж очень хотелось стать посвященным. Мне некоторое время пришлось блуждать в интернете, прежде чем я попал на страничку к Josh Sommer, где он открыл занавес над волнующим меня вопросом. В русском же варианте урока я так и не нашел— посему решил самостоятельно написать таковой, для нашего любимого Демиарта. Причем доступный и открытый для масс код уже более усовершенствован в сравнении с 2005 годом, и несколько проблем связанных с системой, выбоинами и прочими неудобствами вам уже не будут ведомы — они, как персонажи древних мифов, были повержены на злобу новой реальности и канули в лету. Вообще, историю мытарства и доступности для широкого круга, вы, если захотите, сможете прочесть по оригинальной ссылке или ознакомится с моим облегченным вариантом перевода на русский язык, что я скрыл внизу темы:

[700x450]

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

Давайте же приступим друзья, мне больше нечего скрывать, наш экскурс итак затянулся!

[700x450]

Шаг 01 первый, подготовительный


Что нам нужно для похода? Наперво то, без чего вы не читаете новые уроки — интернет разумеется.
Для работы скачайте бесплатную программку, косящую под фотошоп — Gimp (версию не ниже 2.4), именно в ней мы будем творить (если у вас почему-то не получается скачать с офсайта, то я, на всякий случай залил ту версию Гимпа, что юзал при написании урока:
gimp-2.6.8-i686-setup.rar). Стоит отметить, что у этой программы есть ряд отличительных и полезных достоинств. Теперь загружаем необходимый плагин mathmap (1.3.5 for Windows) (файл вложен внизу поста, примечание Natariel) или — даю вам ссылку сразу на закачку установочного файла обновившейся версии — с ней будет меньше мороки и есть свой бонус (в следующей части я об этом упомяну).

Установите Gimp и плагин. При установке, хитроумный Gimp автоматически определяет ваше географическое местоположение, и при включении, так как он мультиязычный, запустит русифицированную версию (зависит от того, что у вас выбрано в "региональных параметрах"). И все же, если нужно или хочется работать в англоязычном пространстве, то смену на другой язык в параметрах самой программы вы пока не найдете. Самый удобный вариант исправить это неудобство — создать файл запуска для определенного языка. Откройте блокнот и вставьте в него следующий текст:

CODE
set lang=en
start gimp-2.6.exe

Сохраните это дело как GIMP-EN.BAT (расширение bat обязательно). Учтите, что если у вас другая версия Гимпа, нежели 2.6, то в записи нужно указывать вашу версию.

Таким образом, оригинальный ярлык будет запускать русскую версию, а созданный батовский файл — нужный языковой аналог (для других языков ставим соответствующие сокращения, например: =fr или =de):

[700x416]

Шаг 02 Подбор и подготовка изображения


Какого плана нужны мечи с кастами для славной бойни картинки для эффекта? Желательно выбирать такие изображения, где имеется наличие, помимо прочего, объектов схожих с замкнутыми геометрическими примитивами, таких как круги, прямоугольники, треугольники… — внутренняя часть которых не несет важного акцента (т.к. ее придется удалить — в любом случае ее не будет видно). Первыми объектами, что приходят на ум и бросаются в глаза, естественно станут: глаза и открытые рты местных детишекgrin, дверные и иные проемы, циферблаты, картинные рамки, тарелки, объективы, мониторы, окна, чашки и прочая геометрия городского типа. На самом деле вариантов великое множество и с опытом вы сможете расширить применение сего эффекта в более художественном направлении. Данный эффект уже применяли даже в современной рекламе и клипах — как же без этого.

 Поскольку в этой части мы просто знакомимся с основами, то возьмем материал попроще: циферблат и рамку — на подобных примитивах проще всего уяснить для себя стартовый принцип работы кода в наглядном виде. Для дополнительной "литературности", можете скачать изображение человека с рамкой в руках (также находится в приложении к посту внизу, примечание Natariel), подготовленный Джошем, чтобы получить уже широко распространенный и имеющий успех вид эффекта:

[700x355]

[700x422]

Откройте ваше изображение в Гимпе и удалите его внутреннюю часть. Перед удалением в Гимпе, для начального слоя следует добавить альфа-канал (чтобы получить прозрачные пиксели, а не белую заливку):

[700x422]

Вы можете подготовить изображение и в Фотошопе, например, как это сделал я: удалив внутреннюю часть и заштампировав остатки стрелок, потом сохраните изображение в формате psd и откройте его в Гимпе:

[700x422]

Для пленки я недавно нарисовал также двух персонажей, чтобы сделать ее веселее (это также поможет визуально):

[700x422]

Шаг 03


Итак, картинка открыта в Гимпе и ее серединка коварно удалена. Теперь запустим сам зловещий "фильтр": Filters > Generic > Mathmap > Mathmap:

[700x422]

Итак, вместо текста во вкладке exp​ression вставляем следующий ниже код и жмем Preview (строчка кода начатая с октоторпа, его составной (влияющей на саму работу) не является, но после него есть пояснения и его наличие ничем не мешает).

Это десятая версия кода обновленная в 2007 году, о чем в самом коде также указано:

CODE
################################################################
# Код для эффекта Дросте, версия 10 для Mathmap 1.2.0
# Оригинальная формула представлена:
# breic ( www.flickr.com/photos/breic )
# Добавленные функции и заточка для Mathmap 1.2 сделаны:
# Josh Sommers ( www.flickr.com/photos/joshsommers )
# Также можете посмотреть изображение получаемые изображения в группе: www.flickr.com/groups/escherdroste
# Последняя модификация: 6/10/2007
################################################################

############################################################
## You should not need to change anything below this line ##
############################################################

filter droste (
image in,
float InnerRadius: 1 - 100 (25),
int OuterRadius: 1 - 100 (100),
float Periodicity: -6 - 6 (1),
int Strands: -6 - 6 (1),
int Zoom: 1-100 (1),
int Rotate: -360-360 (0),
int XShift: -100 - 100 (0),
int YShift: -100 - 100 (0),
int XCenterShift: -100 - 100 (0),
int YCenterShift: -100 - 100 (0),
int StartingLevel: 1-20 (1),
int NumberOfLevels: 1-20 (10),
int LevelFrequency: 1-10 (1),
bool ShowBothPoles,
int PoleRotation: -180-180 (90),
int PoleLong: -100-100 (0),
int PoleLat: -100-100 (0),
bool TilePoles,
bool HyperDroste,
int FractalPoints: 1-10 (1),
bool AutoSetPeriodicity,
bool NoTransparency,
bool ExternalTransparency,
bool MirrorEffect,
bool Untwist,
bool DoNotFlattenTransparency,
bool ShowGrid,
bool ShowFrame)


#Set code variables from user variables
r1= InnerRadius/100;
r2= OuterRadius/100;
p1= Periodicity;
p2= Strands;
xCenterShift = XCenterShift/100;
yCenterShift = YCenterShift/100;
xShift = (XShift*W/X)/100;
yShift = (YShift*H/Y)/100;
tileBasedOnTransparency = !(NoTransparency);
transparentPointsIn = !(ExternalTransparency);
levelsToLookOut=StartingLevel;
levelToShow=LevelFrequency;
retwist=!(Untwist);

if (AutoSetPeriodicity) then
p1= p2/2 * (1+sqrt(1-(log(r2/r1)/pi)^2));
end;

#Set Rotation
if p1 > 0 then
rotate=-(pi/180) * Rotate;
else
rotate=(pi/180) * Rotate;
end;

#Set Zoom
zoom=((Zoom+InnerRadius-1)/100);

epsilon=.01;

#######################
# Set up the viewport #
#######################
if (retwist) then
xbounds=[-r2,r2];
ybounds=[-r2,r2];
else
ybounds=[0,2.1*pi];
xbounds=[-log(r2/r1), log(r2/r1)];
end;

minDimension=min(W, H);
xymiddle=ri:[0.5*(xbounds[0]+xbounds[1]),0.5*(ybounds[0]+ybounds[1])];
xyrange=xy:[xbounds[1]-xbounds[0], ybounds[1]-ybounds[0]];
aspectRatio=W/H;
xyrange[0]=xyrange[1]*aspectRatio;
xbounds=[xymiddle[0]-0.5*xyrange[0],xymiddle[0]+0.5*xyrange[0]];
z=ri:[xbounds[0]+(xbounds[1]-xbounds[0])*(x+W/2)/W,ybounds[0]+(ybounds[1]-ybounds[0])*(y+H/2)/H];

# only allow for procedural zooming/scaling in the standard coordinates
if (retwist) then
zinitial=z;
z = z - ri:[xShift,yShift];
z=xymiddle+(z-xymiddle)/zoom*exp(-I*rotate);
else
zinitial=r1*exp(z); # save these coordinates for drawing a frame later
zinitial=zinitial*Zoom*exp(I*rotate);
end;

if ShowBothPoles then
theta=(pi/180)*PoleRotation;
xx = z[0];
yy = z[1];
div = .5 * (1+ xx^2 + yy^2 + ((1-xx^2-yy^2) * cos(theta)) - (2 * xx * sin(theta)));
xx = xx * cos(theta) + (0.5*(1 - xx^2 - yy^2) * sin(theta));
z = ri:[xx,yy];
z = z/div;
else

if HyperDroste then
z = sin(z);
end;

if TilePoles then

z = z^FractalPoints;
z = tan(2*z);
end
end;

pLat = (PoleLat*W/X)/100;
pLon = (PoleLong*W/X)/100;
z= z + ri:[pLat,pLon];

if (retwist) then
z2=log(z/r1);
else
z2 = z;
end;

##################################
# Droste-effect math starts here #
##################################

alpha=atan(p2/p1*log(r2/r1)/(2*pi));
f=cos(alpha);
beta=f*exp(I*alpha);

# the angle of rotation between adjacent annular levels
if (p2 > 0)
then angle = 2*pi*p1;
else
angle =-2*pi*p1;
end;

if MirrorEffect then
angle=angle/Strands;
end;

z=p1*z2/beta;
rotatedscaledlogz=z; # save these coordinates for drawing a grid later
logz=z2; # save these coordinates for drawing a grid later
z=r1*exp(z);


################################
# Droste-effect math ends here #
################################

if (tileBasedOnTransparency && levelsToLookOut > 0) then
if (!transparentPointsIn) then ratio=r2/r1*exp( I*angle); end;
if ( transparentPointsIn) then ratio=r1/r2*exp(-I*angle); end;
z = z * (ratio^levelsToLookOut)/1;
end;

colorSoFar=rgba:[0,0,0,0];
alphaRemaining=1;
ix=minDimension/2*(z[0]+xCenterShift);
iy=minDimension/2*(z[1]+yCenterShift);
iXY = xy:[ix,iy];

ColorOut=in(iXY);
colorSoFar = colorSoFar = colorSoFar + (ColorOut*(alpha(ColorOut)*alphaRemaining));
alphaRemaining=alphaRemaining*(1-alpha(ColorOut));
sign=0;

if (tileBasedOnTransparency) then
if ( transparentPointsIn && alphaRemaining > epsilon) then
sign=-1;
end;
if (!transparentPointsIn && alphaRemaining > epsilon) then
sign= 1;
end;
else
radius=sqrt(z[0]*z[0]+z[1]*z[1]);
if (radius < r1) then sign=-1; end;
if (radius > r2) then sign= 1; end;
end;

if (sign < 0) then
ratio=r2/r1*exp( I*angle);
end;

if (sign > 0) then
ratio=r1/r2*exp(-I*angle);
end;

if (levelToShow > 1) then
ratio = exp(log(ratio)*levelToShow);
end;

iteration=StartingLevel;
maxiteration=NumberOfLevels+StartingLevel-1;

while (sign != 0 && iteration < maxiteration) do
z2=z*ratio;
z=z2;
rotatedscaledlogz=rotatedscaledlogz+ri:[0,-sign*angle];
ix=minDimension/2*(z[0]+xCenterShift);
iy=minDimension/2*(z[1]+yCenterShift);
iXY = xy:[ix,iy];
sign=0;
if (tileBasedOnTransparency) then
ColorOut=in(iXY);
colorSoFar = colorSoFar + (ColorOut*(alpha(ColorOut)*alphaRemaining));
alphaRemaining=alphaRemaining*(1-alpha(ColorOut));
if ( transparentPointsIn && alphaRemaining > epsilon) then sign=-1; end;
if (!transparentPointsIn && alphaRemaining > epsilon) then sign= 1; end;
else
radius=sqrt(z[0]*z[0]+z[1]*z[1]);
colorSoFar=in(iXY);
if (radius < r1) then sign=-1; end;
if (radius > r2) then sign= 1; end;
end;
iteration=iteration+1;
end;

ColorOut=colorSoFar;

if (ShowGrid) then
gridz=xy:[(logz[0]+10*log(r2/r1))%log(r2/r1), (logz[1]+10*2*pi)%(2*pi)];

if (gridz[0] < epsilon || gridz[0] > (log(r2/r1)-epsilon) || gridz[1] < epsilon || gridz[1] > (2*pi-epsilon)) then
ColorOut=rgba:[0,1,0,1];
end;

gridz=xy:[(rotatedscaledlogz[0]+10*log(r2/r1))%log(r2/r1), (rotatedscaledlogz[1]+10*2*pi)%(2*pi)];

if (gridz[0] < epsilon || gridz[0] > (log(r2/r1)-epsilon) || gridz[1] < epsilon || gridz[1] > (2*pi-epsilon)) then ColorOut=rgba:[0,0,1,1];
end;
end;

if (ShowFrame) then
gridz=xy:[zinitial[0],zinitial[1]];
if (gridz[0] < (aspectRatio*r2) && gridz[0] > -(aspectRatio*r2) && gridz[1] < r2 && gridz[1] > -r2) then
dx=min((aspectRatio*r2)-gridz[0], gridz[0]+(aspectRatio*r2));
dy=min(r2-gridz[1], gridz[1]+r2);
if (dx < (4*epsilon) || dy < (4*epsilon)) then
ColorOut=rgba:[1,1,1,1];
end;
if (dx < (2*epsilon) || dy < (2*epsilon)) then
ColorOut=rgba:[0,0,0,1];
end;
else
ColorOut=rgba:[0.75*red(ColorOut),0.75*green(ColorOut),0.75*blue(ColorOut),1];
end;
end;

if !(DoNotFlattenTransparency) then
ColorOut=rgba:[ColorOut[0], ColorOut[1], ColorOut[2], 1];
end;

ColorOut

end

[700x422]

Дальше перейдите на вкладку User Values, где увидите ползунки-параметры, сгенерированные кодом, которые будут влиять на изображение (раньше настройки менялись напрямую в коде, с постоянным обновлением Preview, а самих настроек было меньше):

[700x548]

Шаг 04


Что представляет собой этот плагин вы уже наверное догадались — он позволяет воплощать математическую фантазию фанатиков-матеМагов)), вернее с его помощью можно изменить/трансформировать картинку посредством математических формул и хитростей. Более конкретно о его прелестях мы, отчасти, коснемся в другом уроке, а сейчас вернемся к нашей теме. Картинка у нас будет закручиваться относительно вырезанной области.

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

InnerRadius — указывает на процент величины внутреннего радиуса изображения от оригинального размера.
OuterRadius — указывает процент внешнего радиуса.
Пикселизацию, которую вы будете видеть в окошке предварительного просмотра, не бойтесь — ее на готовой картинке не будет:

[700x548]

Periodicity — количество повторов исходного изображения за каждый виток. Если задать значение два, то на один виток изображение будет накручено два раза. В примере с циферблатом это будет выглядеть так: при значении Periodicity = 1, в одном витке будут цифры от 1 до 12, при значении Periodicity = 2 эти цифры повторятся дважды за круг (поскольку здесь циферблат не идеально круглый, то он исказился до овала):

[700x548]

[700x548]

Strands — задает количество спиралей. При значении 0 получим эффект зеркала напротив зеркала. Значение 1 — одна спираль, значение 2 — две… и т.д.. Отрицательные цифры завернут спираль в обратную сторону (против часовой стрелки). Лучше всего это станет понятно, при включенном параметре Show Grid (вспомогательная функция), где зеленым цветом отображены внутреннее и внешнее кольца радиусов. Синий цвет показывает саму закрутку и количество спиралей. Главное, если этого не нужно специально, снять эту галочку до нажатия кнопки Ок, иначе сетка тоже будет присутствовать на готовой картинке.

Значение = 0 (снова напоминаю про пикселизацию, при применении эффекта изображение будет нормальным):

[700x318]

Strands = 1 (слева); Strands = 2 (справа):

[700x628]

И еще раз:

[700x628]

Значения параметров Periodicity и Strands имеют взаимосвязь. Есть определенная формула удачных взаимозначений обоих параметров, помимо целых чисел — таблицу и формулу мы рассмотрим в другой теме, тем более, что это еще зависит и от правильной зеркальной геометричности рамки (все намного проще чем я запряг в этом предложении). Например, в данных примерах не все имеющиеся удачные комбинации будут получаться из-за разности толщины ободка часов и той же пленки (левая часть тоньше)

Продолжение следует

Автор урока: Manoylov AC

Урок основан и был бы невозможен без выложенной информации от
Josh Sommer (первый вариант урока)

Источник

 

Серия сообщений "Разное":
Часть 1 - Программа для рисования фракталов
Часть 2 - Роспись по стеклу. Мастер-класс
...
Часть 23 - Частые вопросы по выбору фотоаппарата
Часть 24 - Напольные подушки в интерьере
Часть 25 - Рекурсия, Эффект Дросте. Часть 1
вверх^ к полной версии понравилось! в evernote


Вы сейчас не можете прокомментировать это сообщение.

Дневник Рекурсия, Эффект Дросте. Часть 1 | Svetlana_200170 - Дневник S200170 | Лента друзей Svetlana_200170 / Полная версия Добавить в друзья Страницы: раньше»