xxxxxxxxxx
195
// Hilbert Curve
// Coding in the Cabana
// The Coding Train / Daniel Shiffman
// https://thecodingtrain.com/CodingInTheCabana/003-hilbert-curve.html
// https://youtu.be/dSK-MW-zuAc
// interpolation by Cameron Brown @z6v
const orderMax = 5;
let order = 1;
let N;
let total;
let n2;
let total2;
let path = [];
let otherPath = [];
let otherDest = [];
let counter = 0;
let delta = 0.01;
let orderDelta = 1;
function setup() {
createCanvas(512, 512);
colorMode(HSB, 360, 255, 255);
background(0);
setupCurves(order, order + 1);
}
function draw() {
background(0);
stroke(255);
strokeWeight(1);
noFill();
//beginShape();
for (let i = 1; i < Math.max(total, total2); i++) {
let h = map(i, 0, otherPath.length, 0, 360);
stroke(h, 255, 255);
let c = counter;
if(orderDelta < 0)
c = 1.0 - c;
let pointa = lerpvec(otherPath[i - 1], otherDest[i - 1], c);
let pointb = lerpvec(otherPath[i], otherDest[i], c);
line(pointa.x, pointa.y, pointb.x, pointb.y);
}
counter += delta;
if (counter > 1) {
order += orderDelta;
if (order > orderMax-1)
orderDelta = -1;
else if (order < 2)
orderDelta = 1;
else if(orderDelta > 0)
setupCurves(order, order + 1);
else
setupCurves(order-1, order);
counter = 0;
}
//endShape();
// strokeWeight(4);
// for (let i = 0; i < path.length; i++) {
// point(path[i].x, path[i].y);
// text(i, path[i].x+5, path[i].y);
// }
}
function setupCurves(fromOrder, toOrder) {
N = int(pow(2, fromOrder));
total = N * N;
n2 = int(pow(2, toOrder));
total2 = n2 * n2;
path = [];
otherPath = [];
otherDest = [];
for (let i = 0; i < total; i++) {
path[i] = hilbert(i, fromOrder);
let len = width / N;
path[i].mult(len);
path[i].add(len / 2, len / 2);
}
if (toOrder > fromOrder) {
for (let i = 0; i < total2; ++i) {
let thisAmount = (i / total2) * total;
let thisIndex = Math.floor(thisAmount);
otherPath[i] = {};
otherPath[i].x = path[thisIndex].x;
otherPath[i].y = path[thisIndex].y;
let otherIndex = thisIndex + 1;
if (otherIndex >= path.length)
otherIndex = thisIndex;
otherPath[i] = lerpvec(path[thisIndex], path[otherIndex], thisAmount - thisIndex);
otherDest[i] = hilbert(i, toOrder);
let len = width / n2;
otherDest[i].mult(len);
otherDest[i].add(len / 2, len / 2);
}
}
}
function hilbert(i, o) {
const points = [
new p5.Vector(0, 0),
new p5.Vector(0, 1),
new p5.Vector(1, 1),
new p5.Vector(1, 0)
];
let index = i & 3;
let v = points[index];
for (let j = 1; j < o; j++) {
i = i >>> 2;
index = i & 3;
let len = pow(2, j);
if (index == 0) {
let temp = v.x;
v.x = v.y;
v.y = temp;
} else if (index == 1) {
v.y += len;
} else if (index == 2) {
v.x += len;
v.y += len;
} else if (index == 3) {
let temp = len - 1 - v.x;
v.x = len - 1 - v.y;
v.y = temp;
v.x += len;
}
}
return v;
}
function lerpvec(pa, pb, t) {
t = EasingFunctions.easeInOutQuint(t);
let result = {
x: pa.x,
y: pa.y
};
result.x += (pb.x - pa.x) * t;
result.y += (pb.y - pa.y) * t;
return result;
//return result;
}
/*
* Easing Functions - inspired from http://gizma.com/easing/
* only considering the t value for the range [0, 1] => [0, 1]
*/
EasingFunctions = {
// no easing, no acceleration
linear: t => t,
// accelerating from zero velocity
easeInQuad: t => t * t,
// decelerating to zero velocity
easeOutQuad: t => t * (2 - t),
// acceleration until halfway, then deceleration
easeInOutQuad: t => t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
// accelerating from zero velocity
easeInCubic: t => t * t * t,
// decelerating to zero velocity
easeOutCubic: t => (--t) * t * t + 1,
// acceleration until halfway, then deceleration
easeInOutCubic: t => t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
// accelerating from zero velocity
easeInQuart: t => t * t * t * t,
// decelerating to zero velocity
easeOutQuart: t => 1 - (--t) * t * t * t,
// acceleration until halfway, then deceleration
easeInOutQuart: t => t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t,
// accelerating from zero velocity
easeInQuint: t => t * t * t * t * t,
// decelerating to zero velocity
easeOutQuint: t => 1 + (--t) * t * t * t * t,
// acceleration until halfway, then deceleration
easeInOutQuint: t => t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t
}