Sticky

#### Version 10 of the Droste Effect Code

MOD
Here is the newest version of the droste effect code. A big thanks goes out to Breic for his help in adding in the ability to see both poles.

There are a lot of new features, and so there are a lot of new sliders and checkboxes too.

I have written some brief documentation of the new features at the beginning of the formula.

I hope you enjoy!

Here are a few samples of images that can be created with this new version:

HERE IT IS:
################################################################
# Droste effect code version 10 for Mathmap 1.2.0
# Original Droste formula by:
# breic ( www.flickr.com/photos/breic )
# Additional Features and Mathmap 1.2 conversion by:
# Josh Sommers ( www.flickr.com/photos/joshsommers )
# Also see the flickr group: www.flickr.com/groups/escherdroste
################################################################

#Decription of User Values:

###New Settings in Version 10###
#ShowBothPoles: Select this option to see both poles of the droste effect. This means you will see one pole where Periodicity=-1 and one where Periodicity=1. Note that you may need to increase the values of StartingLevel and NumberOfLeves when you use this option.

#PoleRotation: Rotation of the pole when ShowBothPoles is true. At +/-90 you will see both poles. At 0 and +/-180 you will see just one pole.

#PoleLat: Use in conjunction with the ShowBothPoles, TilePoles or HyperDroste options. Latitude adjustment.

#PoleLong: Same as PoleLat, but for Longitude adjustment.

#TilePoles: Cannot be used at the same time as ShowBothPoles. Set this option to tile the poles horizontally.

#HyperDroste: A cool fractal-like droste effect.

#FractalPoints: Use in conjuntion with TilePoles and or HyperDroste settings to create fractal like droste images.

###Old Settings Pre Version 10###
#InnerRadius: The percentage of the overall image that you want to be occupied by the spiral.
#OuterRadius: The percentage size of the overall image that you want to use in the effect.
#Periodicity: The number of times the image is repeated on each iteration of the spiral.
#Strands: The number of strands/arms the spiral will have.
#Zoom: Zoom in or out of the spiral.
#Rotate: Rotate the spiral. Positive numbers rotate clockwise.
#XShift: Shift the image on the X axis. Positive numbers shift to the right.
#YShift: Shift the image on the Y axis. Positive numbers shift upwards.
#XCenterShift: Shift the center of the spiral on the X axis. Positive numbers shift to the right.
#YCenterShift: Shift the center of the spiral on the Y axis. Positive numbers shift upwards.
#StartingLevel: The level that the spiral starts at. For internal transparency or no transparency, the first level is the outermost level. For outer transparency, the first level is the innermost level.
#NumberOfLevels: The total number of repetitions of the spiral.
#LevelFrequency: The frequency of levels. If set at 1, you will get every level. If set at 2 you will get every other level. If set at 3 you will get every third level, and so on.
#AutoSetPeriodicity: If set to true, the optimal value for Periodicity will be set for you.
#NoTransparency: Set to true if you do not wish to tile based upon a transparent region in your image.
#ExternalTransparency: Set the to true if the transparent region is on the outside of the image. The default is false, indicating that the transparent region is on the inside of the image.
#MirroEffect: Only works when using multiple strands. Set to true to mirror strands.
#Untwist: Set to true to see the image in log coordinates.
#DoNotFlattenTransparency: Set to true to leave semi-transparent pixels semi-transparent.
#Show Grid: The green grid shows each basic annulus, with (outer radius)/(inner radius) = r2/r1. The blue grid shows the green grid mapped into log coordinates (in which it truly is a grid), rotated, and exponentiated forward again. This allows visualization of the Droste transformation.
#ShowFrame: The frame is a black-and-white border in the standard view, and its preimage in the log coordinates. In log coordinates, the shaded region to the right of the frame will be mapped outside the viewport, while the region to the left will be visible.

############################################################
## 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
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

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
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
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
i'm really curious to try the new features...thank for doing it

the examples are really interesting
It loolks very impressive. I can't get it to run, however. I get the following error when I try to use it.

MathMap Message
Exactly one filter must be defined.

I checked through the code and it doesn't look to have more than one filter defined in it but I'm scratching my head on this.

Greg
MOD
Greg- You have to delete the filter that is already defined by default before you paste in a new one. The expression box should be completely empty before you paste in the droste filter.
josh, thanks for posting the code. it was your tutorial that started me of f on this and i will always be grateful for that. now, you continue to share your discoveries and enhancements. thank you.
MOD
Manyone1- You are welcome! And I in turn have to thank Breic because it was he who shared with me and enabled me to do everything I have done with the formula, and inspired me to go back and re-learn complex analysis (still working on that though...).
MOD
Note to everyone:

If you find that the spirals are no longer infinite when you use the new features, try increasing the values of StartingLevel and NumberOfLevels. I have found that StartingLevel=6 and NumberOfLevels=13 works about right when using the ShowBothPoles feature.
I opened notepad and pasted it in there. Then I saved it in the expressions folder as Droste_10.mm and Gimp sees it, but gives the message I listed above. I havent tried putting it in through the Gimp's interface. It shouldn't make a difference but I'll try anything.

Thanks Again,

Greg
OK. I tried putting it in through Gimps Mathmap interface and it worked! Will Miracles never cease! Now should I try animating it???

Thanks Yet Again!

Greg
MOD
For issues with Mathmap, it is probably better to post to the mathmap group.
I like some issues of this version, especially the possibility to choose tenths instead of integer values for radius. Again, I'm coming with the question of saving the chosen variables for the final image. I've lost some photos and I have only the originals, I have to remake them but I'm sure I'll never find the former values. Thank again for sharing your extraordinary work.
saving the variables would be useful .

In the time while i take a screenshoot of the setting before pressing ok. and i
include the preview window in the screenshoot for easier the search later

So when needed i can copy the values from the screenshoot...not so handy as directly saving preset but could help
The idea of screenshoot is nice, it's so simple and affordable, I could think only complicated solutions. After searching a lot for best shape, pressing OK is like a relief, and often one can forget to write down the values so could be nice to have a question something as "do you want to save the chosen values" and save somewhere a TXT file with these. Might be possible to save something with the final picture file like the metadata. I don't know, I'm just a user not creator like others. I thank again to all of you who worked hard and are working hard for these and sharing them with other people.
admittedly i am an absolute beginner at this, but i am having the same problem as photomastergreg i totally remove all previous code from the expression box and copy in the code posted here but when i press preview i get the following error from GIMP: undefined variable filter

can anyone help ( i am fully prepared for an embrarassing 'its right under you nose' response)
MOD
TGRoberts- You are using version 1.2 code in an older version of mathmap, presumably mathmap cocoa. For mathmap cocoa you cannot use formulas that use the new syntax, you have to use old formulas that are compatible with version 1.0.1 of mathmap. If the formula begins with either "filter" or "unit filter" then it is for mathmap 1.2.0, so you need to use formulas that do not begin with "filter" or "unit filter". For the droste effect, try version 7 or below. Everything after version 7 is for mathmap 1.2.0.
Thank you , I saw you appeared on boingboing yesterday, congrats.
Thanks a lot for the code..
i also made few images from this :)
still on experimentation..
Hi all!
Im pretty new to mathmap and trying to experiment some droste effect.
I installed plugin 1.2.4 on gimp 2.4.1 on WIndows2K and droste effect in the packet seems to work well.
I then installed the version 10 (through mathmap interface I pasted and saved it as Droste_10.mm) but cannot get it to work...
Here is the error I'm getting:
** ERROR **: file compiler.c: line 2076 (simplify_zero): should not be reached aborting....
MOD
Sounds like a problem with the version of Mathmap you are using. I would suggest that you might want to consider going back to an earlier version of mathmap 1.2. The last version that I tested this code on was 1.2.0 (and that is the version I still use because of the introduction of several bugs with subsequent versions). You should be able to still get the setup.exe for 1.2.0 in the mathmap group.
sure i know that

, but is strange that the bug afflict only version 9 and 10 of the droste code (maybe 8 too ?) and no the others codes and not even your older codes
actually I dont know as I didnt try with older Droste versions (just the one that comes with mathmap packet)...is there a link to a version older than 10?
yes each was posted on this list
hi! was wondering if this is the latest version of your code? thanks in advance.. i have used it already awhile ago - might try it again for kicks ;) your work is impressive! thank you
MOD
Yeah, this is the newest version.
great post, thank you everyone very much
JOSH i'm triing to make your tutorial with the newest version but i'm obtaing in the preview only horizontal lines no drost effect yet.

Gimp 2.4+mathmap 1.2.1 win xp.

I can't understand where i get wrong. can someone help me?
MOD
Sorry, I have no idea what the problem could be. You didn't change the formula at all did you? In this version, you don't change the formula, you just change the sliders.
change your computer local setting to english..(from control panel/language options)

That will NOT change the language of your PC ( that is impossible in XP, the MS require youbuy a new OS for that...or upgrade to one of most expensive version of vista )that only changes how number are formatted

Actually i bet that for 1 thousand and 5 cents you have in cipher 1.000,05 but English standard for that is 1,000.05 (note the point instead then the comma)

that will make MM almost unusable ,but solution is very simple

From the control panel/international option (sorry my PC is not in english so name in english may be a bit different that is the sense)
you may change only that option the other ones are for calendar display and currency used..in any case you do not risk to change language )
MOD
I think in English it is called "Regional Settings".
Do you think there could be a way to make the code run under any regional setting ? I have 0 knowledge of i18n and the like, but I guess it could be possible to recognize the regional setting and adapt to it, don't you think ?

I have a some spare time ahead of me, if someone could point me in the right direction I'd be happy to help.
For those of you who got horizontal lines or just the background colour (I had the same problem) :

I guess you are using Windows Vista. Mathmap is trying to access some files in the plugin folder which is in the program area (wild guess), and as Vista is really a S*** it will not give access to it as long as you do not run gimp in Administrator mode.
So, best is to disable UAC (Google: Disable The UAC Nag), and run the programme with right mouse, selecting "Run as Administrator". HTH.
is it regional setting? - maybe this is a tittle
commented by Canon T1i
muzika_doremi

well if called "regional setting" should be no problem, should be a english version of xp and so should have numbers as default already formatted in the english style...so MM should work

Problem is with other languages but then only MS know how "regional setting" was translated..( i.e in Italian version, "regional setting where translated as " language options"..even if no one of that "options" can't change the language)
Dear Josh

I have just used yr provided image from droste effect tutorial (beginner) and insert it to Gimp ver.2.6.0 + Mathmap ver.1.2.4 + ver.10 of droste effect formula. It is WORK....... let me so happy...... admittedly I am an absolute beginner at this. Yeah, of course I have to adjust the parameter valves in user tap (don't know the valve right or wrong) to get the similar spiral image.
It is hard for me as a beginner to understand the relationship between the parameter valves inside the user tap. But I will try my best to learn.
Thanks for posting the code and yr tutorial that started me off on this. I will always be grateful for that.

Thanks again
Sam
Groups Beta