Skip to content

Instantly share code, notes, and snippets.

@remixz
Created January 27, 2023 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remixz/ca136abc3abf6eb2b7c09a441279696e to your computer and use it in GitHub Desktop.
Save remixz/ca136abc3abf6eb2b7c09a441279696e to your computer and use it in GitHub Desktop.
Voronoi Triangles Paradox
const colors = [
"#f2dfd8",
"#f6e3dd",
"#f7e6df",
"#f9e8e1",
"#fae8e4",
"#fae9e2",
"#f8e5d7",
"#fae8dc",
"#fcebe1",
"#fdece2",
"#fdebdf",
"#f8dcc4",
"#fde1c9",
"#fee4cd",
"#fee6ce",
"#ffe5ce",
"#fee2ca",
"#fde2c7",
"#c6b9b0",
"#d2c2b5",
"#d9c7bb",
"#dac8ba",
"#dac7b9",
"#d3c1b5",
"#cab9af",
"#cfc1be",
"#a0a5a9",
"#9b9b9d",
"#a2a4a3",
"#606a69",
"#7b7f80",
"#acaead",
"#7d8587",
"#7b8386",
"#7a8285",
"#71797b",
"#5c6763",
"#636d6c",
"#636d6f",
"#5e6464",
"#626868",
"#646867",
"#656968",
"#606664",
];
const cellCount = 72;
let points, delaunay, polygons;
let triangles = [];
let iteration = 0;
const baseTriangle = {
count: 0
}
function setup () {
// print or save size
createCanvas(800, 800);
colorMode(HSB, 360, 100, 100, 1);
background(color("#29313E"));
points = [...Array(cellCount)].map(() => {
return [
Math.floor(random(0, width)),
Math.floor(random(0, height))
];
});
delaunay = d3.Delaunay.from(points);
polygons = delaunay.trianglePolygons();
for (const triangle of polygons) {
triangles.push(triangle);
}
createTriangle(baseTriangle, iteration, triangles);
setColor(baseTriangle);
calculateStep(baseTriangle);
// scale canvas to fit on screen
const canvasElement = document.querySelector(".p5Canvas");
const canvasRatio = canvasElement.height / canvasElement.width;
const windowRatio = window.innerHeight / window.innerWidth;
let cssHeight;
let cssWidth;
if (windowRatio < canvasRatio) {
cssHeight = window.innerHeight;
cssWidth = cssHeight / canvasRatio;
} else {
cssWidth = window.innerWidth;
cssHeight = cssWidth * canvasRatio;
}
canvasElement.style.width = `${cssWidth * 0.75}px`;
canvasElement.style.height = `${cssHeight * 0.75}px`;
}
const createTriangle = (baseTriangle, iteration, triangles) => {
baseTriangle.a = {
x: triangles[iteration][0][0],
y: triangles[iteration][0][1]
}
baseTriangle.b = {
x: triangles[iteration][1][0],
y: triangles[iteration][1][1]
}
baseTriangle.c = {
x: triangles[iteration][2][0],
y: triangles[iteration][2][1]
}
return baseTriangle;
}
const setColor = (baseTriangle) => {
baseTriangle.strokeColor = tinycolor(random(colors)).setAlpha(0.7).toHslString();
baseTriangle.fillColor = tinycolor(baseTriangle.strokeColor).setAlpha(0.1).toHslString();
return baseTriangle;
}
const calculateStep = (baseTriangle) => {
const sides = [
dist(baseTriangle.a.x, baseTriangle.a.y, baseTriangle.b.x, baseTriangle.b.y),
dist(baseTriangle.b.x, baseTriangle.b.y, baseTriangle.c.x, baseTriangle.c.y),
dist(baseTriangle.c.x, baseTriangle.c.y, baseTriangle.a.x, baseTriangle.a.y)
];
sides.sort((a, b) => a - b);
baseTriangle.step = Math.floor(sides[0] / random([5, 8, 8, 8, 13]));
return baseTriangle;
}
const lerpPoints = (point1, point2, step) => {
const x = lerp(point1.x, point2.x, step);
const y = lerp(point1.y, point2.y, step);
return {x, y};
}
const updateTriangle = (baseTriangle) => {
baseTriangle.a = lerpPoints(baseTriangle.a, baseTriangle.b, 0.1);
baseTriangle.b = lerpPoints(baseTriangle.b, baseTriangle.c, 0.1);
baseTriangle.c = lerpPoints(baseTriangle.c, baseTriangle.a, 0.1);
baseTriangle.count = baseTriangle.count + 1;
baseTriangle.step = baseTriangle.step - 1;
return baseTriangle;
}
const drawTriangle = (pointA, pointB, pointC) => {
triangle(
pointA.x,
pointA.y,
pointB.x,
pointB.y,
pointC.x,
pointC.y
);
}
function draw () {
if(iteration <= cellCount * 2) {
fill(color(baseTriangle.fillColor))
stroke(color(baseTriangle.strokeColor));
triangle(
baseTriangle.a.x,
baseTriangle.a.y,
baseTriangle.b.x,
baseTriangle.b.y,
baseTriangle.c.x,
baseTriangle.c.y
);
if(baseTriangle.step > 0) {
updateTriangle(baseTriangle);
} else {
iteration++;
createTriangle(baseTriangle, iteration, triangles);
calculateStep(baseTriangle);
setColor(baseTriangle);
}
} else {
noLoop();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.5.2/tinycolor.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-delaunay@6"></script>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
}
body {
background: radial-gradient(circle at center, #878889, #2f353f);
display: grid;
place-items: center;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment