public
Created

Trying Ammann Beenker tiling in Processing

  • Download Gist
tiling.pde
Processing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
float magic = 1+sqrt(2);
int maxLevel = 2;
 
void setup()
{
size(1280, 800);
background(255);
smooth();
fill(255);
 
//drawRhombus(150, 30, 4000, 0, 0);
drawRectangle(0, 0, 1280, 0, 0);
}
 
void drawRhombus(float x, float y, float diagonal, float deg, int level)
{
if(level == maxLevel)
stroke(0);
else
stroke(255);
// a rhombus is actually just 4 right sided triangles, where each hypotenuse is the side of the rhombus.
// let's do some right sided triangle magic to find hypotenuse from the angle (45/2) and the adjacent (diagonal / 2)
float sideLength = (diagonal / 2.0) / cos(radians(45.0/2));
 
pushMatrix();
translate(x, y);
rotate(radians(deg));
// figure out skewing of rhombus and draw it
PVector skew = new PVector(sin(radians(45.0)) * sideLength, cos(radians(45.0)) * sideLength);
quad(0.0, 0.0, 0.0, sideLength, skew.x, skew.y + sideLength, skew.x, skew.y);
 
// draw children
if(level < maxLevel)
{
// find small diagonal of rhombus by using the pythagorean theorem:
// getting the opposite from the hypotenuse (sidelength) and angle (45 / 2)
float shortDiagonal = sin(radians(45.0/2.0)) * sideLength;
drawRhombus(0.0, 0.0, shortDiagonal * 2.0, 0.0, level + 1);
drawRhombus(0.0, 0.0 + sideLength, shortDiagonal * 2.0, -90, level + 1);
drawRhombus(skew.x, skew.y + sideLength, shortDiagonal * 2.0, -180, level + 1);
// rectside length is equal to the small rhombus side length
float rectSide = (shortDiagonal / 2.0) / cos(radians(45.0/2.0));
float rectDiagonal = rectSide * sqrt(2); // have to be multiplied by 2
drawRectangle(skew.x - (rectSide * 2.0), rectDiagonal + (rectSide * 2.0), rectSide * 2.0, -90, level + 1);
drawRectangle(skew.x + (rectDiagonal), skew.y + (rectDiagonal), rectSide * 2.0, 135, level + 1);
drawRectangle(-rectDiagonal, sideLength - rectDiagonal, rectSide * 2.0, -45, level + 1);
drawRectangle(rectSide * 2.0, sideLength, rectSide * 2.0, 90, level + 1);
}
popMatrix();
}
 
void drawRectangle(float x, float y, float sideLength, float deg, int level)
{
if(level == maxLevel)
stroke(0);
else
stroke(255);
pushMatrix();
translate(x, y);
rotate(radians(deg));
// draw big rect
rect(0, 0, sideLength, sideLength);
//ellipse(0, sideLength, 10, 10);
// draw children
if(level < maxLevel)
{
// draw rects
float shortRectSide = sideLength / magic;
// in a square, the diagonal is the side multipled by the sq. root of 2
float shortRectDiagonal = shortRectSide * sqrt(2);
drawRectangle(shortRectDiagonal/2, shortRectDiagonal / 2, shortRectSide, 135, level + 1);
drawRectangle(shortRectDiagonal/2 + shortRectSide, shortRectDiagonal / 2 + shortRectSide, shortRectSide, 180, level + 1);
drawRectangle(sideLength - (shortRectDiagonal/2), (shortRectDiagonal / 2), shortRectSide, -135, level + 1);
drawRectangle(sideLength + (shortRectDiagonal / 2), (shortRectDiagonal / 2), shortRectSide, 135, level + 1);
drawRectangle(sideLength - (shortRectDiagonal/2), sideLength + (shortRectDiagonal / 2), shortRectSide, -135, level + 1);
// find rhombus diagonal from its hypotenuse
float rhompDiagonal = cos(radians(45.0/2.0)) * shortRectSide;
drawRhombus(0, 0, rhompDiagonal * 2, -45, level + 1);
drawRhombus(0, sideLength, rhompDiagonal * 2.0, -90, level + 1);
drawRhombus(0, sideLength, rhompDiagonal * 2.0, -135, level + 1);
drawRhombus(sideLength - (shortRectDiagonal/2), shortRectDiagonal / 2, rhompDiagonal * 2, 0, level + 1);
}
popMatrix();
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.