xxxxxxxxxx
// dimensions
let width = 1000;
let height = 1000;
let inc = width/125;
let modes = ["argyle", "geometric1", "geometric2", "lines"];
// global variables
var depth = 7; // 7 good for argyle, 5 good for the rest
var minimumDepth = 2;
var mode = modes[0]; // argyle
let arg_palette = ["#a41623","#f85e00","#ffb563","#ffd29d"];
// let arg_palette = ["#ef8311", "#FFD400", "#29f0b6", "#3965f5", "#ea3788"]; // lines cyber
let arg_bg = "#918450";
// let palette = ["#a41623","#f85e00", "#FC8A32", "#ffb563","#ffd29d", "#918450"];
let lines_palette = ['#f70640', '#f78e2c', '#fdd903', '#cae509', '#63be93', '#81cfe5', '#299dbf', '#a4459f', '#f654a9', "#9913bf"];
// let palette = ["#00CECB", "#ffb703", "#3965f5", "#fb8500"];
// let palette = ["#0863d3", "#f5d216", "#f43809", "#08b233", "#9913bf"]; // RK
// let palette = ["#ee6c4d","#9c95dc","#662c91","#17a398", "#56E39F","#d7f171"]
// let geometric2_palette = ["#3131d1", "#ef8311", "#34bbfb", "#FFC21F"];
let geometric2_palette = ["#fe5b14", "#ff9831", "#cec8b8", "#000000", "#372821"];
// let geometric2_palette = ["#ef8311", "#FFD400", "#29f0b6", "#3965f5", "#ea3788"];
// let geometric2_palette = ["#000000", "#CFB87C", "#7f7f7f", "#CFB87C", "#ffffff"];
let bg = "#000";
function setup() {
createCanvas(width, height);
noLoop();
rectMode(CORNERS);
strokeWeight(2);
let gui = new dat.GUI();
gui.add(this, 'depth', 1, 10, 1);
gui.add(this, 'minimumDepth', 0, depth, 1);
gui.add(this, "mode", modes);
gui.add(this, 'generate');
generate();
}
function generate() {
clear();
let bgswitch = (mode == "argyle" ? arg_bg : bg);
background(bgswitch);
subdivide(0, 0, width, height, depth);
}
class Rectangle {
constructor(x1, y1, x3, y3) {
this.x1 = x1;
this.y1 = y1;
this.x3 = x3;
this.y3 = y3;
this.width = abs(x3 - x1);
this.height = abs(y3 - y1);
this.centerX = (x1 + x3) / 2;
this.centerY = (y1 + y3) / 2;
// this.area = this.width * this.height;
}
display() {
switch (mode) {
case "argyle":
this.display_arg();
break;
case "geometric1":
this.display_geometric1();
break;
case "geometric2":
this.display_geometric2();
break;
case "lines":
this.display_lines();
break;
}
}
display_arg() {
let shuffledcols = shuffle(arg_palette);
stroke("#FC8A32");
// stroke("#08b233");
if (random() > 0.5) {
// if (true) {
fill(shuffledcols[1]);
} else {noFill();}
if (random() > 0.5) {
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
} else {
line(this.x1, this.y1, this.x3, this.y3);
}
}
display_geometric1() {
let shuffledcols = shuffle(lines_palette);
noStroke();
fill(shuffledcols[0]);
rect(this.x1, this.y1, this.x3, this.y3);
if (random() > 0.25) {
fill(shuffledcols[1]);
switch(random([1,2,3,4])) {
case 1:
arc(this.x1, this.y1, this.width*2, this.height*2, 0, HALF_PI);
break;
case 2:
arc(this.x1, this.y3, this.width*2, this.height*2, PI + HALF_PI, 2 * PI);
break;
case 3:
arc(this.x3, this.y3, this.width*2, this.height*2, PI, PI + HALF_PI);
break;
case 4:
arc(this.x3, this.y1, this.width*2, this.height*2, HALF_PI, PI);
break;
}
}
}
display_geometric1_offsets() {
let shuffledcols = shuffle(lines_palette);
noStroke();
fill(shuffledcols[0]);
rect(this.x1, this.y1, this.x3, this.y3);
if (random() > 0.25) {
// fill(shuffledcols[1]);
let w = this.width*2;
let i = 1;
let arcmin = inc/2;
switch(random([5,6,7,8])) {
case 1:
arc(this.x1, this.y1, this.width*2, this.height*2, 0, HALF_PI);
break;
case 2:
arc(this.x1, this.y3, this.width*2, this.height*2, PI + HALF_PI, 2 * PI);
break;
case 3:
arc(this.x3, this.y3, this.width*2, this.height*2, PI, PI + HALF_PI);
break;
case 4:
arc(this.x3, this.y1, this.width*2, this.height*2, HALF_PI, PI);
break;
case 5:
while (w > arcmin) {
fill(shuffledcols[i % 2]);
arc(this.x1, this.y1, w, w, 0, HALF_PI);
w -= inc;
i++;
}
break;
case 6:
while (w > arcmin) {
fill(shuffledcols[i % 2]);
arc(this.x1, this.y3, w, w, PI + HALF_PI, 2 * PI);
w -= inc;
i++;
}
break;
case 7:
while (w > arcmin) {
fill(shuffledcols[i % 2]);
arc(this.x3, this.y3, w, w, PI, PI + HALF_PI);
w -= inc;
i++;
}
break;
case 8:
while (w > arcmin) {
fill(shuffledcols[i % 2]);
arc(this.x3, this.y1, w, w, HALF_PI, PI);
w -= inc;
i++;
}
break;
}
} else {
let cx1 = this.x1;
let cy1 = this.y1;
let cx3 = this.x3;
let cy3 = this.y3;
let i = 1;
while (cx3 - cx1 > inc / 2) {
fill(shuffledcols[i % 2]);
rect(cx1, cy1, cx3, cy3);
cx1 += inc / 2;
cy1 += inc / 2;
cx3 -= inc / 2;
cy3 -= inc / 2;
i++;
}
}
}
display_geometric2() {
// let shuffledcols = shuffle(arg_palette);
let randIndex = floor(random(geometric2_palette.length));
// stroke(palette[randIndex]);
// let x1 = this.x1;
// let y1 = this.y1;
// let x3 = this.x3;
// let y3 = this.y3;
noStroke();
switch (random(["rect", "rectcircle", "rectsquare", "diagline"])) {
case "rect":
fill(geometric2_palette[randIndex % geometric2_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
break;
case "rectcircle":
fill(geometric2_palette[randIndex % geometric2_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
fill(geometric2_palette[(randIndex + 1) % geometric2_palette.length]);
circle(this.centerX, this.centerY, this.width*0.5);
break;
case "rectsquare":
fill(geometric2_palette[randIndex % geometric2_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
fill(geometric2_palette[(randIndex + 1) % geometric2_palette.length]);
rect(this.x1 + this.width*0.25, this.y1+ this.width*0.25, this.x3 - this.width*0.25, this.y3 - this.width*0.25)
break;
case "diagline": // diagonal line
fill(geometric2_palette[randIndex % geometric2_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
fill(geometric2_palette[(randIndex + 1) % geometric2_palette.length]);
if (random() > 0.5) {
triangle(this.x1, this.y1, this.x1 + this.width, this.y1, this.x1 + this.width, this.y1 + this.height);
} else {
triangle(this.x1, this.y1, this.x1, this.y1 + this.height, this.x1 + this.width, this.y1);
}
break;
}
}
display_lines() {
noFill();
let randIndex = floor(random(lines_palette.length));
// stroke(palette[randIndex]);
let x1 = this.x1;
let y1 = this.y1;
let x3 = this.x3;
let y3 = this.y3;
switch (random(["rectcircle", "rectcross", "offsetrects", "diagline", "offsetdiaglines", "X"])) {
case "rectcircle":
stroke(lines_palette[randIndex % lines_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
stroke(lines_palette[(randIndex + 1) % lines_palette.length]);
circle(this.centerX, this.centerY, this.width*0.5);
break;
case "rectcross":
stroke(lines_palette[randIndex % lines_palette.length]);
rect(this.x1, this.y1, this.x3, this.y3); // uses rectMode(Corners)
stroke(lines_palette[(randIndex + 1) % lines_palette.length]);
line(this.centerX - this.width*0.2, this.centerY, this.centerX + this.width*0.2, this.centerY);
line(this.centerX, this.centerY + this.height*0.2, this.centerX, this.centerY - this.height*0.2);
break;
case "offsetrects":
while (x1 < x3) {
stroke(lines_palette[randIndex % lines_palette.length]);
rect(x1, y1, x3, y3); // uses rectMode(Corners)
x1 += inc;
x3 -= inc;
y1 += inc;
y3 -= inc;
randIndex += 1;
}
break;
case "diagline": // diagonal line
stroke(lines_palette[randIndex % lines_palette.length]);
if (random() > 0.5) {
line(this.x1, this.y1, this.x3, this.y3);
} else {
line(this.x1, this.y3, this.x3, this.y1);
}
break;
case "offsetdiaglines": // diagonal lines
if (random() > 0.5) {
while (x1 < x3) {
stroke(lines_palette[randIndex % lines_palette.length]);
line(x1, y1, x3, y3);
x1 += inc*sqrt(2);
y3 -= inc*sqrt(2);
randIndex += 1;
}
} else {
while (x1 < x3) {
stroke(lines_palette[randIndex % lines_palette.length]);
line(x1, y1, x3, y3);
x3 -= inc*sqrt(2);
y1 += inc*sqrt(2);
randIndex += 1;
}
}
break;
case "X": // diagonal line
stroke(lines_palette[randIndex % lines_palette.length]);
line(this.x1, this.y1, this.x3, this.y3);
line(this.x1, this.y3, this.x3, this.y1);
break;
}
}
}
function subdivide(x1, y1, x3, y3, depthLevel) {
if (depthLevel == 1) { // base case
if (mode == "argyle") {
// do nothing
} else {
let rec = new Rectangle(x1, y1, x3, y3);
rec.display();
}
} else {
/*
POINTS: ↺
x1, y1 -------
| |
------- x3, y3
*/
// let half = (x1 + x3) / 2; makes a mondrian effect
let half = (x3 - x1) / 2;
let ax1 = x1, ay1 = y1;
let ax3 = x1 + half, ay3 = y1 + half;
let bx1 = x1, by1 = y1 + half;
let bx3 = x1 + half, by3 = y3;
let cx1 = x1 + half, cy1 = y1 + half;
let cx3 = x3, cy3 = y3;
let dx1 = x1 + half, dy1 = y1;
let dx3 = x3, dy3 = y1 + half;
let minDepth = depth - minimumDepth;
let toDivide1 = (depthLevel > minDepth ? true : random() < 0.5);
let toDivide2 = (depthLevel > minDepth ? true : random() < 0.5);
let toDivide3 = (depthLevel > minDepth ? true : random() < 0.5);
let toDivide4 = (depthLevel > minDepth ? true : random() < 0.5);
// if (depthLevel > minDepth && random() < 0.5) {
// if (toDivide) {
// // if (true) {
// subdivide(ax1, ay1, ax3, ay3, depthLevel - 1);
// subdivide(bx1, by1, bx3, by3, depthLevel - 1);
// subdivide(cx1, cy1, cx3, cy3, depthLevel - 1);
// subdivide(dx1, dy1, dx3, dy3, depthLevel - 1);
// } else {
// let recA = new Rectangle(ax1, ay1, ax3, ay3);
// let recB = new Rectangle(bx1, by1, bx3, by3);
// let recC = new Rectangle(cx1, cy1, cx3, cy3);
// let recD = new Rectangle(dx1, dy1, dx3, dy3);
// recA.display();
// recB.display();
// recC.display();
// recD.display();
// }
if (toDivide1) {
subdivide(ax1, ay1, ax3, ay3, depthLevel - 1);
} else {
let rec = new Rectangle(ax1, ay1, ax3, ay3);
rec.display();
}
if (toDivide2) {
subdivide(bx1, by1, bx3, by3, depthLevel - 1);
} else {
let rec = new Rectangle(bx1, by1, bx3, by3);
rec.display();
}
if (toDivide3) {
subdivide(cx1, cy1, cx3, cy3, depthLevel - 1);
} else {
let rec = new Rectangle(cx1, cy1, cx3, cy3);
rec.display();
}
if (toDivide4) {
subdivide(dx1, dy1, dx3, dy3, depthLevel - 1);
} else {
let rec = new Rectangle(dx1, dy1, dx3, dy3);
rec.display();
}
}
}