|
|
As requested, here is some code for generating Penrose tilings.
This was my development code, with some comments added. It just produces
a plain tiling image in a similar fashion to fractint.
A scene file for the penrose flooring in my images will hopefully be
following as soon as I have edited it!
global_settings{
assumed_gamma 1.0
}
#include "colors.inc"
#include "math.inc"
#declare s18=sin(1*pi/10); // sin 18 degrees
#declare s36=sin(2*pi/10); // etc
#declare s54=sin(3*pi/10);
#declare s72=sin(4*pi/10);
#declare phi=(sqrt(5)+1)/2;
#declare bd=0.04; //rhomb outline thickness
#declare it=3; // level of recursion 0=none 10=lots 11=can't allocate a
big block of memory!
// create an array to store positions of tiles at each
recursion level, to weed out duplicates
// just a crude array indexed by nearest integer of x co-ord
and y co-ord and orientation of tile.
#declare g_size=ceil(2.4*pow(phi,it)); // calc integer size of
array needed, prob a little larger than needed
#declare got=array[g_size*2+1][g_size*2+1][10][it+1]; // x * y * 10 * recursion
level
// the objects to be used as
tiles.
// un-commenting the spheres
will show the orientation of the tiles
#declare fat=union{ // sphere{<s54/2,0>,s54*s36/4 texture{pigment{colour
Red}finish{ambient 1}}}
polygon{
5,<bd/s36,0>,<s54,s36-bd/s54>,<2*s54-bd/s36,0>,<s54,-s36+bd/s54>,<bd/s36,0>
texture{
pigment{colour Yellow}
finish{ambient 1}
}
}
polygon{
5,<0,0>,<s54,s36>,<2*s54,0>,<s54,-s36>,<0,0>
translate z/100
texture{
pigment{colour Gray20}
finish{ambient 1}
}
}
}
#declare thin=union{ // sphere{<s18/2,0>,s18*s72/4 texture{pigment{colour
Red}finish{ambient 1}}}
polygon{
5,<bd/s72,0>,<s18,s72-bd/s18>,<2*s18-bd/s72,0>,<s18,-s72+bd/s18>,<bd/s72,0>
texture{
pigment{colour Blue}
finish{ambient 1}
}
}
polygon{
5,<0,0>,<s18,s72>,<2*s18,0>,<s18,-s72>,<0,0>
translate z/100
texture{
pigment{colour Gray20}
finish{ambient 1}
}
}
}
// this macro inflates the fat
rhombs
#macro inf_fat(posn,angl,levl) // takes tile position,
orientation and current recursion level
#declare a1=1.2*posn.x+g_size; // calc indexes to array to see if
this tile has been done before
#declare a2=1.2*posn.y+g_size; // 1.2 multiplier controls
granularity of indexing, lowering reduces resolution of array, raising increases
memory usage.
// must change size of
array above in concert with this.
#declare a3=mod((floor((angl+378)/36)),10);
#ifndef (got[a1][a2][a3][levl]) // only execute the rest of the
macro if the array index has not been defined yet
// we're about to do the current
rhomb so let's define the array element so we know in future not to do it again.
#declare got[a1][a2][a3][levl]=1; // comment out this line to
disable the duplication checking to compare number of scene level objects, memory
usage and parse/render times
#if (levl=0)
object{fat rotate z*angl translate posn} // if at last recursion level then
we draw a real tile
#else //if levl=0
// if not then we call the macros
recursively to substitute this 'tile' with several others
#if (angl<0) #declare angl=angl+360; #end
#if (angl>360) #declare angl=angl-360; #end // pull angle into 0-360 range
inf_fat((posn*phi+vrotate(<1+2*s54,0>,z*angl)),angl+180,levl-1) // scale
current position by golden ratio
inf_fat((posn*phi+vrotate(<1+s18,s72>,z*angl)),angl-144,levl-1) // add offset
for subst tiles, rotating by the orientation of the tile
inf_fat((posn*phi+vrotate(<1+s18,-s72>,z*angl)),angl+144,levl-1) // and also
reduce the recursion level by one to avoid infinite loops
inf_thin((posn*phi+vrotate(<1+s18,s72>,z*angl)),angl-36,levl-1)
inf_thin((posn*phi+vrotate(<1+s18,-s72>,z*angl)),angl+36,levl-1)
#end //if levl
#end //ifndef
#end //macro inf_fat
// this macro inflates thin
rhombs, works same as above.
#macro inf_thin(posn,angl,levl)
#declare a1=1.2*posn.x+g_size;
#declare a2=1.2*posn.y+g_size;
#declare a3=mod((floor((angl+378)/36)),10);
#ifndef (got[a1][a2][a3][levl])
#declare got[a1][a2][a3][levl]=1; // comment out this line to
disable the duplication checking to compare number of scene level objects, memory
usage and parse/render times
#if (levl=0)
object{thin rotate z*angl translate posn}
#else
#if (angl<0) #declare angl=angl+360; #end
#if (angl>360) #declare angl=angl-360; #end
inf_thin((posn*phi+vrotate(<1,0>,z*angl)),angl+108,levl-1)
inf_thin((posn*phi+vrotate(<1,0>,z*angl)),angl-108,levl-1)
inf_fat((posn*phi+vrotate(<s54-s18,s36+s72>,z*angl)),angl-108,levl-1)
inf_fat((posn*phi+vrotate(<s54-s18,-s36-s72>,z*angl)),angl+108,levl-1)
#end //if
#end //ifndef
#end //macro inf_thin
camera{
// tiles are placed in x,y plane,
look at from -z axis
right<4,0,0>
up<0,3,0>
direction<0,0,10>
location<0,0,-12*pow(phi,it)>//2 // this gets the whole tiling visible by moving
the camera in and out - tag '/2' to the end to zoom in and fill the whloe screen
look_at<0,0,0>
}
inf_fat(<0,0>,18,it) // 5 seed tiles to kick the whole thing
off.
inf_fat(<0,0>,90,it) // These can be changed, but that may
require changes to the duplicate checking if any are away from the origin
inf_fat(<0,0>,162,it)
inf_fat(<0,0>,234,it)
inf_fat(<0,0>,306,it)
--
Alex
Post a reply to this message
|
|