float centreX, centreY, r, theta;
float transformFactor,transformFactorMin, transformFactorMax;
background(255, 255, 255);
transformFactorMax = 150;
float dx = tileSize * cos(radians(30)) * 2;
int startval = int(random(5));
for (float y = 0.0; y < height + tileSize; y += tileSize/2) {
for (float x = l % 2 * dx / 2; x < width + tileSize; x += dx) {
if (showHexagon) { stroke(21,212,224); } else { stroke(255);}
blankModule(x,y,tileSize);
strokeWeight(max(1, int(5*(transformX(width,0)-width/2)/sqrt(sq(transformX(x,y)-width/2)+sq(transformY(x,y)-width/2)))));
int randnum = int(random(5));
module(x, y, tileSize, randnum, 0);
module(x, y, tileSize, randnum, +1);
module(x, y, tileSize, randnum, -1);
if (showHexagon) { stroke(21,212,224); } else { stroke(255);}
blankModule(x, y, tileSize);
strokeWeight(max(1, int(5*(transformX(width,0)-width/2)/sqrt(sq(transformX(x,y)-width/2)+sq(transformY(x,y)-width/2)))));
module(x, y, tileSize, startval,0);
module(x, y, tileSize, startval, 1);
module(x, y, tileSize, startval, -1);
float dx = tileSize * cos(radians(30.0)) * 2.0;
int l = (int) random(2 * height / tileSize);
float y = l * tileSize / 2.0;
float x = l % 2 * dx / 2 + (int) random(width / dx) * dx;
if (showHexagon) { stroke(21,212,224); } else { stroke(255);}
blankModule(x, y, tileSize);
strokeWeight(max(1, int(5*(transformX(width,0)-width/2)/sqrt(sq(transformX(x,y)-width/2)+sq(transformY(x,y)-width/2)))));
int randnum = int(random(5));
module(x, y, tileSize, randnum, 0);
module(x, y, tileSize, randnum, 1);
module(x, y, tileSize, randnum,-1);
if (key == 'h' || key == 'H') {
showHexagon = !showHexagon;
if (key == 'f' || key == 'F') {
randomFlip = !randomFlip;
if (key == 'r' || key == 'R') {
if (key == 'o' || key == 'O') {
if (key == '.' || key == '>') {
if (transformFactor > transformFactorMin) {
if (key == ',' || key == '<') {
if (transformFactor < transformFactorMax) {
float transformX(float x, float y) {
float r = sqrt(cx*cx + cy*cy);
return width/2 + width*atan(r/transformFactor)/PI*cos(PI+atan2(cy,cx));
float transformY(float x, float y) {
float r = sqrt(cx*cx + cy*cy);
return height/2 + width*atan(r/transformFactor)/PI*sin(PI+atan2(cy,cx));
void blankModule(float cx, float cy, float size) {
float side = size * tan(radians(30));
for (int i = 0; i <= 6; i++) {
vertex(transformX( cx + side*cos(i*PI/3),cy+side*sin(i*PI/3)),
transformY( cx + side*cos(i*PI/3),cy+side*sin(i*PI/3)));
void module(float cx, float cy, float size, int rotation, int bShadow) {
int startCurveRotation = rotation + 2;
float arcCentreX,arcCentreY;
float side = size * tan(radians(30));
float smallArcRadius = (side / 2) + 0.7*bShadow;
float bigArcRadius = size * cos(radians(30)) + 0.7*bShadow;
arcCentreX = cx + side*cos(rotation*PI/3);
arcCentreY = cy + side*sin(rotation*PI/3);
curveVertex(transformX(arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3),arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3)),
transformY(arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3),arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3)));
for (float n = 0.0; n <= 10.0; n = n+1.0) {
curveVertex(transformX( arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3+n/10.*2*PI/3),
arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3+n/10.*2*PI/3)),
transformY(arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3+n/10.*2*PI/3),
arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3+n/10.*2*PI/3) ));
curveVertex(transformX(arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3+2.*PI/3),
arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3+2.*PI/3)),
transformY(arcCentreX + smallArcRadius*cos(startCurveRotation*PI/3+2.*PI/3),
arcCentreY+smallArcRadius*sin(startCurveRotation*PI/3+2.*PI/3)));
float arcradius = 2.*side*cos(PI/6.);
float centreangle= 5*PI/6. - float(rotation)*PI/3.;
arcCentreX = cx + arcradius*cos(-centreangle);
arcCentreY = cy + arcradius*sin(-centreangle);
startCurveRotation = rotation;
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3)));
for (float n = 0.0; n <= 10.0; n = n+1.0) {
curveVertex(transformX( arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/10.*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/10.*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/10.*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/10.*PI/3) ));
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+PI/3)));
arcradius = 2.*side*cos(PI/6.);
centreangle= 7.*PI/6. -float(rotation)*PI/3.;
arcCentreX = cx + arcradius*cos(-centreangle);
arcCentreY = cy + arcradius*sin(-centreangle);
startCurveRotation = rotation+5;
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3)));
for (float n = 0.0; n <= (gap-1); n = n+1.0) {
curveVertex(transformX( arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/steps*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/steps*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/steps*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/steps*PI/3) ));
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+ (gap-1)/steps*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+ (gap-1)/steps* PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+ (gap-1)/steps* PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+ (gap-1)/steps*PI/3)));
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3 + (gap+1)/steps*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+(gap+1)/steps*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+(gap+1)/steps*PI/3),arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+(gap+1)/steps*PI/3)));
for (float n = gap+1; n <= steps; n = n+1.0) {
curveVertex(transformX( arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/steps*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/steps*PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+n/steps*PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+n/steps*PI/3) ));
curveVertex(transformX(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+ PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+ PI/3)),
transformY(arcCentreX + bigArcRadius*cos(startCurveRotation*PI/3+ PI/3),
arcCentreY+bigArcRadius*sin(startCurveRotation*PI/3+ PI/3)));