// ********* use processing 2 **************** you can download from processing.org
//------------------------------------------------------------------------------------
// this is the main code to generate the Stampfli tiling
// it shows you how to use the dualization method,
// you can generate other tilings with
// put this code in the main tab of processing at the left
//
// requires the code of "setting up the coordinates - the modified code",
// "class Vector - the code", "saving images - the code"
// these above are the same you may already have copied
// for the programs of the projection method
// and you can reuse them directly
// "combination of grids - the code", "class Grid - the code"
// "class polygons - the code", "class Polygon - the code",
// "class Lines - the code"; "class Line - the code",
// "class Points - the code", "class Point - the code"
// and "testlimits - the code"
// you can reuse this setup to make other tilings with a new main tab
float unitLength;
float xRange,yRange; // visible coordinates from -(xy)Range to +(xy)Range
float sqrt2=sqrt(2.),sqrt05=sqrt(0.5),rt3=sqrt(3.);
float small,lineLenghtSquare;
Grid grid,gridTwo;
void setup(){
size(600,600);
smooth();
unitLength=50; // use a smaller value to get a larger part of the tiling
setupCoordinates();
xRange*=0.85;
yRange*=0.85;
ellipseMode(CENTER);
small=0.01;
grid=new Grid();
gridTwo=new Grid();
}
void draw(){
noLoop();
doTransformations(); // attention: translate and scale are reset at start of draw
background(255);
hexagon(grid);
gridTwo.setTranslation(0.45,0.51); // adjust, to get a different part of the tiling
gridTwo.setRotation(PI/2);
hexagon(gridTwo);
grid=combination(grid,gridTwo);
grid.makeDual();
// now we have got the stampfli tiling, display it ...
trueStrokeWeight(2);
fill(color(255,200,200));
stroke(color(0,0,100));
fill(color(255,128,0));
grid.dualPolygons.showRegular(4);
fill(color(255,0,0));
grid.dualPolygons.showRegular(3);
fill(color(0,255,0));
grid.dualPolygons.showRhomb(PI/6);
//saveImage();
}
//----------------------------------------------------------
//
// hexagon grid
void hexagon(Grid grid) {
int i1, j1, farbe,xLimit,yLimit;
float x1, y1;
float xnull;
yLimit=int(1.2*0.666*yRange);
xLimit=int(1.4*xRange/rt3);
for (j1=-2*yLimit; j1<2*yLimit+2; j1++) {
y1=j1*1.5;
xnull=-rt3/2*(j1%2);
for (i1=-2*xLimit;i1<2*xLimit+2;i1++) {
x1=i1*rt3+xnull;
grid.addGridLine(new Vector(x1, y1+1),new Vector(x1, y1));
grid.addGridLine(new Vector(x1-rt3/2, y1-0.5),new Vector(x1, y1));
grid.addGridLine(new Vector(x1+rt3/2, y1-0.5),new Vector(x1, y1));
}
}
}
Like this:
Like Loading...
Related
Hello! If WordPress is able to show you the email address I provided, could you please get in touch with me? I have made use of your code in a project and want to make sure you are given appropriate credit. Thank you so much for writing this blog; it seems to be the only source of such information on the internet and I learned a lot.
Part 4: Thanks for the reply! I will certainly try using double instead of float and see if that helps.
In the meantime, here is some very hastily thrown together lines of code ( written with a baby on my lap) to see if the multigrid approach work with your program. It looks like your code works perfectly! (But only if unitLength is not too big and not too small.) The following generates a small patch of tiling with five-fold symmetry. Each of the lines below takes the place of an equivalent line of code in the main tab. The grids below ought to be in an array, to make it easier to try other symmetries as well.
Grid grid,gridTwo, gridThree, gridFour, gridFive;
unitLength=30;
small=0.001;
grid=new Grid();
gridTwo=new Grid();
gridThree=new Grid();
gridFour=new Grid();
gridFive=new Grid();
int sym = 5;
float shift = (sym – 1)/(2*sym);
grid.setTranslation(shift, shift);
gridTwo.setTranslation(shift, shift);
gridThree.setTranslation(shift, shift);
gridFour.setTranslation(shift, shift);
gridFive.setTranslation(shift, shift);
float rotangle = 2*PI/sym;
grid.setRotation(rotangle);
gridTwo.setRotation(rotangle*2);
gridThree.setRotation(rotangle*3);
gridFour.setRotation(rotangle*4);
gridFive.setRotation(rotangle*5);
parallel_lines( grid); // instead of calling hexagon, lets try parallel lines as was suggested
parallel_lines(gridTwo);
parallel_lines(gridThree);
parallel_lines(gridFour);
parallel_lines(gridFive);
grid=combination(grid,gridTwo);
grid=combination(grid,gridThree);
grid=combination(grid,gridFour);
grid=combination(grid,gridFive);
void parallel_lines(Grid grid) {
float i;
for (i = -xRange; i<xRange; i++) {
grid.addGridLine(new Vector(i, -yRange),new Vector(i, yRange));
}
}
Part 3: Replacing “grid.dualPolygons.showRegular” and “grid.dualPolygons.showRhomb” with just plain “grid.dualPolygons.show” makes the program less finicky and allows for many more tiles to be displayed. Of course, the display is monochrome — thats fine for me, but maybe thats antithetical to Geometry In *Color* !!! 🙂
The answer to the “bug” seem to be finding the right ratio between the “small” variable and the “unitLength” variable. When I make the “small” variable smaller, I’m able to make tilings with smaller unit lengths. But if I make it too small, the program either produces tilings with holes, or runs without stopping (or maybe I’m not being patient enough). It is no surprise if tilings with lots of tiles take longer to generate, but I’m not sure if I’m on the right track here – is there something else that should be changed? Thanks!
The variable “unitLength” determines how many pixels correspond to one unit of length. Smaller values of “unitLength” give a larger part of the tiling with smaller tiles. But this needs larger numbers in the calculation and some points of the combined grid might be closer to each other. Thus numerical errors become more important.
The variable “small” controls numerics. Because of finite precision we cannot directly compare floating point numbers to see if they are equal. Two numbers are considered to be equal, if their difference is smaller than “small”. Larger tilings and smaller “unitLength” require smaller values for “small”. Thus, we need more numerical precision to create larger tilings. Using the type “double” might do it.
The program requires a lot of time for larger tilings. It goes to the second power of the number of points and the fourth power of the length of a side of the tiling (in terms of “unitLength”). Reducing “unitLength” by a factor of 2 thus increases computing time by a factor of 8 ! This could be improved by more intelligent programming.
I like the way you set this up, where the hexagon grid is in the main tab where it can be easily replaced or modified – I’m looking forward to creating other kinds of grids, and seeing how they combine.
I’m also very curious about whether, if we create the right pair of grids, this method can approximate the deBruijn multigrid method that produces rhombic tilings.
But I think there is a bug to iron out first! When I tried the code as posted above, it worked very well. Then I tried to make unit length smaller. For values above 19 or 20 or so, it appears to works great, but for a unit length of 18 or smaller, there are errors and a tiling isn’t produced. Is this true for you as well?
Thanks for sharing your thoughts !
If I remember correctly, this program is essentially the deBruijn multigrid method if we use infinite straight lines. I cannot verify this because I am far away from a university with a good mathematical library and I have not enough time.
Problems may arise because of finite numerical precision. You could try to replace single precision “float” by double precision “double” in type declarations. This might require some adjustments in other places too.