The creation of optical illusions has always intrigued me. Hexagrams have always been a favorite geometric pattern of my and most importantly, the ability to create depth by underlaying and overlaying different portions. This ended up being more difficult than I had hoped as with p5js, drawings always layer based upon where in the function each element is created. For this reason, I had to separate one side of the hexagram into two pieces to actually create the illusion I wanted which resulted in a lot of calculations and math.
sketchDownload
//side length of the hexagon that a hexagram is based upon
var s = 50
function setup() {
createCanvas(3.5*3*s, 12*s*sqrt(3)/2);
background(150);
noLoop();
}
function draw() {
//translates the center of the canvas to the center of the first hexagram
translate(3/2*s, 2*s*sqrt(3)/2);
//loop creates the gradient effect of the background
for (var i = 0; i<width/10; i++) {
for (var j = 0; j<height/10; j++) {
push();
//translates to start at the top left corner of the canvas
translate(-3/2*s, -2*s*sqrt(3)/2);
//varies the color based on the variables of the loop
fill(255/height*j*10+50, 255/height*j,255/height*j*10+50, 255);
noStroke();
//draws squares based upon the variables of the loop
rect(i*10, j*10, 10, 10);
pop();
}
}
//loops creates the repeating pattern of hexagrams
for(var i = 0; i<width/(3*s); i++) {
for (var j = 0; j<height/(4*s*sqrt(3)/2); j++) {
push();
//translates based upon variables to draw the grid of hexagrams
translate(150*i, 4*s*sqrt(3)/2*j);
//rotates the hexagrams to create the hourglass patterns
rotate(radians(60*i));
rotate(radians(60*j));
//draws the hexagram
opticHexagram();
pop();
}
}
}
//I acknowledge code that is unused should be deleted, however the following
//block comment is necessary to show the math done to create the visual.
//Each function is a building block to the final opticHexagram
/*function hexagon() {
line(-s/2, -s*sqrt(3)/2, s/2, -s*sqrt(3)/2)
line(s/2, -s*sqrt(3)/2, s, 0)
line(s, 0, s/2, s*sqrt(3)/2)
line(s/2, s*sqrt(3)/2, -s/2, s*sqrt(3)/2)
line(-s/2, s*sqrt(3)/2, -s, 0)
line(-s, 0, -s/2, -s*sqrt(3)/2)
}
function spikes() {
triangle(-s/2, -s*sqrt(3)/2, s/2, -s*sqrt(3)/2, 0, -2*s*sqrt(3)/2);
triangle(s/2, -s*sqrt(3)/2, s, 0, 3/2 * s, -s*sqrt(3)/2);
triangle(s, 0, s/2, s*sqrt(3)/2, 3/2 * s, s*sqrt(3)/2);
triangle(s/2, s*sqrt(3)/2, -s/2, s*sqrt(3)/2, 0, 2*s*sqrt(3)/2);
triangle(-s/2, s*sqrt(3)/2, -s, 0, -3/2 * s, s*sqrt(3)/2);
triangle(-s, 0, -s/2, -s*sqrt(3)/2, -3/2 * s, -s*sqrt(3)/2);
}
function hexagram() {
noFill();
triangle(0, -2*s*sqrt(3)/2, 3/2 * s, s*sqrt(3)/2, -3/2 * s, s*sqrt(3)/2);
triangle(3/2 * s, -s*sqrt(3)/2, 0, 2*s*sqrt(3)/2, -3/2 * s, -s*sqrt(3)/2)
line(0, -2*s*sqrt(3)/2, 3/2 *s, s*sqrt(3)/2);
line(3/2 * s, s*sqrt(3)/2, -3/2 * s, s*sqrt(3)/2);
line(-3/2 * s, s*sqrt(3)/2, 0, -2*s*sqrt(3)/2);
line(3/2 * s, -s*sqrt(3)/2, 0, 2*s*sqrt(3)/2);
line(0, 2*s*sqrt(3)/2, -3/2 * s, -s*sqrt(3)/2);
line(-3/2 * s, -s*sqrt(3)/2, 3/2 * s, -s*sqrt(3)/2);
}
*/
//creates a hexagram with interlacing sides to create an optical illusion
function opticHexagram() {
push();
noStroke();
//half of the white side of the lighter triangle
//this needed to be broken into two pieces in order for the optical illusion
//to work
fill(255);
quad(0, 2*s*sqrt(3)/2,0, .8*2*s*sqrt(3)/2, .8*-3/4 * s, .8*s*sqrt(3)/4,
-3/4*s, s*sqrt(3)/4);
//black side of the dark triangle
fill(0);
quad(.8*-3/2*s, .8*s*sqrt(3)/2 , -3/2*s, s*sqrt(3)/2, 3/2*s, s*sqrt(3)/2,
.8*3/2*s, .8*s*sqrt(3)/2)
//medium side of the lighter triangle
fill(255-50);
quad(.8*3/2 * s, .8*-s*sqrt(3)/2, 3/2 * s, -s*sqrt(3)/2, 0, 2*s*sqrt(3)/2,0,
.8*2*s*sqrt(3)/2)
//medium side of the darker triangle
fill(0+50);
quad(0, -2*s*sqrt(3)/2, 0, .8*-2*s*sqrt(3)/2,.8*3/2*s, .8*s*sqrt(3)/2 ,
3/2*s, s*sqrt(3)/2);
//darkest side of the lighter triangle
fill(255-100);
quad(-3/2 * s, -s*sqrt(3)/2, .8*-3/2 * s, .8*-s*sqrt(3)/2,.8*3/2 * s,
.8*-s*sqrt(3)/2, 3/2 * s, -s*sqrt(3)/2);
//lightest side of the darker triangle
fill(0+100);
quad(0, -2*s*sqrt(3)/2, 0, .8*-2*s*sqrt(3)/2,.8*-3/2*s, .8*s*sqrt(3)/2 ,
-3/2*s, s*sqrt(3)/2);
//other half of the white side of the lighter triangle
//completes the illusion
fill(255);
quad(.8*-3/2 * s, .8*-s*sqrt(3)/2, -3/2 * s, -s*sqrt(3)/2, -3/4 * s,
s*sqrt(3)/4, .8*-3/4*s, .8*s*sqrt(3)/4)
pop();
}