Previous Entry Share Next Entry
Рекурсия, Эффект Дросте
Cat
catreverse
Рекурсия, Эффект Дросте


Рекурсия, Эффект Дросте, Бесконечные картинки
Картинная галерея Эшера

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

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

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

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

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

Рекурсия, Эффект Дросте, Бесконечные картинки
_________________________________________________


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

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

CODE
set lang=en
start gimp-2.6.exe

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

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

Рекурсия, Эффект Дросте, Бесконечные картинки
_________________________________________________


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

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

Рекурсия, Эффект Дросте, Бесконечные картинки
Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки

_________________________________________________


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

Рекурсия, Эффект Дросте, Бесконечные картинки

Итак, вместо текста во вкладке 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


Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки
_________________________________________________


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

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

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки
Рекурсия, Эффект Дросте, Бесконечные картинки

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

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

Рекурсия, Эффект Дросте, Бесконечные картинки

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

Рекурсия, Эффект Дросте, Бесконечные картинки

И еще раз:

Рекурсия, Эффект Дросте, Бесконечные картинки


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

источник http://demiart.ru/forum/index.php?showtopic=137006

?

Log in