xxxxxxxxxx
464
const Scenes = {
"DotProduct" : drawDotProduct,
"SmoothHeight" : drawSmoothHeight,
"SmoothHeightLerp" : drawSmoothHeightLerp,
"MipMaps" : drawMipMaps,
"StepSize": drawStepSize,
}
// const scene = Scenes.DotProduct;
const scene = Scenes.SmoothHeight;
// const scene = Scenes.SmoothHeightLerp;
// const scene = Scenes.MipMaps;
// const scene = Scenes.StepSize;
function setup() {
createCanvas(1920, 1080);
}
function draw() {
background("#62A6A9");
scene();
}
function mouseReleased() {
fullscreen(!fullscreen());
}
function drawDotProduct() {
const n = createVector(0, -1);
const a = frameCount/60 * QUARTER_PI;
const o = createVector(cos(a), sin(a));
const d = n.dot(o);
const mid = createVector(width/2, height/2 + height/8);
const l = height/3;
n.mult(l);
o.mult(l);
strokeWeight(20);
stroke("#477645");
arrow(mid.x, mid.y, mid.x + n.x, mid.y + n.y, 50);
stroke("#D6B69E");
arrow(mid.x, mid.y, mid.x + o.x, mid.y + o.y, 50);
stroke(255)
point(mid.x, mid.y);
fill(255);
noStroke();
textAlign(CENTER, TOP);
textSize(height/10);
text("Dot product: " + d.toFixed(2), mid.x, 50);
}
function drawSmoothHeight() {
const heights = [0.65, 0.6, 0.57, 0.5, 0.48, 0.52, 0.59, 0.66, 0.69, 0.72];
const w = width/(heights.length - 1);
let t = frameCount/240 % 6;
// t = 1 + mouseX/width;
const tBlank = constrain(t, 0, 1);
const tRaise = constrain(t, 1, 2) - 1;
const tRayMove1 = constrain(t, 2, 3) - 2;
const tSmoothPlot = constrain(t, 3, 4) - 3;
const tRayMove2 = constrain(t, 4, 5) - 4;
const rayX = width/6 + tRayMove1 * width * 2/3 - tRayMove2 * width * 2/3;
const getHeight = (i) => {
return heights[i] * height * tRaise * 0.7;
}
const lerpHeight = (x) => {
const p = x/w;
const i = floor(p);
const l = p - i;
const h1 = getHeight(i);
const h2 = getHeight(i + 1);
return lerp(h1, h2, l);
}
const getCombinedHeight = (i) => {
const h1 = getHeight(i);
let h2 = getHeight(i + 1);
h2 = h2 ? h2 : 0;
return lerp(h1, h2, tSmoothPlot);
}
fill("#477645");
stroke(255);
beginShape();
vertex(-5, height);
vertex(-5, height - getHeight(0));
for(let i = 0; i < heights.length; i ++) {
vertex(i * w, height-getHeight(i));
vertex((i + 1) * w, height - getCombinedHeight(i));
}
vertex(width + 5, height - getHeight(heights.length - 1));
vertex(width + 5, height);
endShape();
// if(tSmoothPlot > 0) {
// fill(255, 128);
// strokeWeight(5);
// beginShape();
// vertex(-5, height);
// vertex(-5, height - lerpHeight(0));
// for(let x = 0; x < width * tSmoothPlot; x ++) {
// vertex(x, height - lerpHeight(x));
// }
// vertex(width * tSmoothPlot + 5, height - lerpHeight(width * tSmoothPlot + 5));
// vertex(width * tSmoothPlot + 5, height);
// endShape();
// }
strokeWeight(5);
if(tRayMove1 > 0 && tRayMove1 < 1) {
const p = rayX/w;
const i = floor(p);
const h = height - getHeight(i);
stroke(255);
line(rayX, 0, rayX, h);
noStroke();
fill("#D6B69E");
circle(rayX, h, 20);
}
if(tRayMove2 > 0 && tRayMove2 < 1) {
const h = height - lerpHeight(rayX);
stroke(255);
line(rayX, 0, rayX, h);
noStroke();
fill("#D6B69E");
circle(rayX, h, 20);
}
}
function drawSmoothHeightLerp() {
strokeWeight(5);
const l = height/2;
const tl = 0.2;
const tr = 0.3;
const bl = 0.5;
const br = 0.4;
textSize(50);
const bScale = 4;
textAlign(CENTER, CENTER);
let t = frameCount/240 % 4;
// t = 2 + mouseX/width;
const tPoint = constrain(t, 0, 1);
const tHLerp = constrain(t, 1, 2) - 1;
const tVLerp = constrain(t, 2, 3) - 2;
const fadeLevel = map(tHLerp, 0.8, 1, 255, 128);
fill(tl * 255, fadeLevel);
stroke(255, fadeLevel);
rect(width/2 - l/2 - l/bScale, height/2 - l/2 - l/bScale, l/bScale, l/bScale);
fill(255, fadeLevel);
noStroke();
text(tl.toFixed(1), width/2 - l/2 - l/(bScale * 2), height/2 - l/2 - l/(bScale * 2));
fill(tr * 255, fadeLevel);
stroke(255, fadeLevel);
rect(width/2 + l/2, height/2 - l/2 - l/bScale, l/bScale, l/bScale);
fill(255, fadeLevel);
noStroke();
text(tr.toFixed(1), width/2 + l/2 + l/(bScale * 2), height/2 - l/2 - l/(bScale * 2));
fill(bl * 255, fadeLevel);
stroke(255, fadeLevel);
rect(width/2 - l/2 - l/bScale, height/2 + l/2, l/bScale, l/bScale);
fill(255, fadeLevel);
noStroke();
text(bl.toFixed(1), width/2 - l/2 - l/(bScale * 2), height/2 + l/2 + l/(bScale * 2));
fill(br * 255, fadeLevel);
stroke(255, fadeLevel);
rect(width/2 + l/2, height/2 + l/2, l/bScale, l/bScale);
fill(255, fadeLevel);
noStroke();
text(br.toFixed(1), width/2 + l/2 + l/(bScale * 2), height/2 + l/2 + l/(bScale * 2));
stroke(255);
noFill();
square(width/2 - l/2, height/2 - l/2, l);
const p = createVector(0.3, 0.6);
stroke(255, tPoint * 128);
line(width/2 - l/2, height/2 - l/2 + l * p.y, width/2 + l/2, height/2 - l/2 + l * p.y);
line(width/2 - l/2 + l * p.x, height/2 - l/2, width/2 - l/2 + l * p.x, height/2 + l/2);
const tv = lerp(tl, lerp(tl, tr, p.x), tHLerp);
const bv = lerp(bl, lerp(bl, br, p.x), tHLerp);
const x = width/2 - l/2 + l * p.x * tHLerp;
if(tHLerp > 0) {
stroke(255);
if(tHLerp < 1) {
line(width/2 - l/2, height/2 - l/2 - l/(bScale * 2), width/2 + l/2, height/2 - l/2 - l/(bScale * 2));
line(width/2 - l/2, height/2 + l/2 + l/(bScale * 2), width/2 + l/2, height/2 + l/2 + l/(bScale * 2));
}
line(x, height/2 - l/2 - l/bScale, x, height/2 - l/2);
line(x, height/2 + l/2 + l/bScale, x, height/2 + l/2);
noStroke();
fill(255);
textSize(30);
textAlign(CENTER, BOTTOM);
text(tv.toFixed(3), x, height/2 - l/2 - l/bScale);
textAlign(CENTER, TOP);
text(bv.toFixed(3), x, height/2 + l/2 + l/bScale);
}
if(tVLerp > 0) {
stroke(255);
const y = height/2 - l/2 + l * p.y * tVLerp;
const v = lerp(tv, lerp(tv, bv, p.y), tVLerp);
line(x - l/(bScale * 2), y, x + l/(bScale * 2), y);
noStroke();
fill(255);
textAlign(LEFT, CENTER);
const ty = min(max(y, height/2 - l/2 + l/(bScale * 4)), height/2 - l/2 + l * p.y - l/(bScale * 4));
text(v.toFixed(3), x + l/(bScale * 2) + 5, ty);
}
noStroke();
fill(214, 182, 158, tPoint * 255);
circle(width/2 - l/2 + l * p.x, height/2 - l/2 + l * p.y, 30);
}
function drawMipMaps() {
const m1 = [0.328, 0.227, 0.329, 0.392, 0.574, 0.797, 0.611, 0.475, 0.449, 0.538, 0.669, 0.579, 0.455, 0.317, 0.386, 0.485];
const m2 = mipMap(m1);
const m3 = mipMap(m2);
const m4 = mipMap(m3);
const m5 = mipMap(m4);
const w = width/m1.length;
const h = w/2;
let t = frameCount/120 % 4;
// t = 2.000001 + mouseX/width * 2;
const tMaps = constrain(t, 0, 1);
const tRay1 = constrain(t, 1, 2) - 1;
const tRay2 = constrain(t, 2, 3) - 2;
const tRay3 = constrain(t, 3, 4) - 3;
const getHeight = (arr, i) => {
return height - arr[i] * height * 0.7;
}
stroke(0);
for(let i = 0; i < m1.length; i ++) {
fill(m1[i] * 255);
rect(i * w, 0, w, h);
rect(i * w, getHeight(m1, i), w, height);
if(tMaps > 0.2 && i % 2 == 0 && tRay3 < 0.8) {
let j = floor(i/2);
fill(m2[j] * 255);
rect(i * w, h, w * 2, h);
if(tMaps < 0.4 || tRay3 > 0.6) {
let h = getHeight(m2, j);
line(i*w, h, i * w + w * 2, h);
}
}
if(tMaps > 0.4 && i % 4 == 0 && tRay3 < 0.6) {
let j = floor(i/4);
fill(m3[j] * 255);
rect(i * w, h * 2, w * 4, h);
if(tMaps < 0.6 || tRay3 > 0.4 || (tRay2 > 0.04 && tRay2 < 1)) {
let h = getHeight(m3, j);
line(i*w, h, i * w + w * 4, h);
}
}
if(tMaps > 0.6 && i % 8 == 0 && ((tRay3 > 0 && tRay3 < 0.4) || tRay2 < 0.04)) {
let j = floor(i/8);
fill(m4[j] * 255);
rect(i * w, h * 3, w * 8, h);
if(tMaps < 0.8 || tRay3 > 0.2 || (tRay2 > 0.02 && tRay2 < 0.04)) {
let h = getHeight(m4, j);
line(i*w, h, i * w + w * 8, h);
}
}
if(tMaps > 0.8 && i % 16 == 0 && ((tRay3 > 0 && tRay3 < 0.2) || tRay2 < 0.02)) {
let j = floor(i/16);
fill(m5[j] * 255);
rect(i * w, h * 4, w * 16, h);
if(tRay2 < 0.02 || tRay2 >= 1) {
let h1 = getHeight(m5, j);
line(i*w, h1, i * w + w * 16, h1);
}
}
}
if(tRay1 > 0 && tRay1 < 1) {
fill("#D6B69E");
noStroke();
circle(width * 3/4 * (1 - tRay1), height/3 + h/2, 20);
}
if(tRay2 > 0 && tRay2 < 1) {
fill("#D6B69E");
noStroke();
const t = constrain((tRay2 - 0.04)/0.96, 0, 1);
circle(width - 60 - (width/4 - 70) * t, height * 5/8, 20);
}
if(tRay3 > 0 && tRay3 < 1) {
fill("#D6B69E");
noStroke();
circle(width * 11/13, height * 3/4 + h/2, 20);
}
}
function drawStepSize() {
strokeWeight(5);
const heights = [0.53, 0.57, 0.68, 0.7, 0.75, 0.81, 0.8, 0.65, 0.6, 0.57, 0.5, 0.48, 0.4, 0.34, 0.37, 0.42, 0.52, 0.59, 0.66, 0.69, 0.72];
const w = width/(heights.length - 1);
let t = frameCount/60 % 7;
// t = (mouseX/width) * 4;
const tV1 = constrain(t, 0, 1);
const tH1 = constrain(t, 1, 2) - 1;
const tScale = (constrain(t, 2.1, 4.1) - 2.1) / 2;
const tRay1 = (constrain(t, 4.2, 6.2) - 4.2) / 2;
const getHeight = (i) => {
return heights[i] * height;
}
const lerpHeight = (x) => {
const p = x/w;
const i = floor(p);
const l = p - i;
const h1 = getHeight(i);
const h2 = getHeight(i + 1);
return lerp(h1, h2, l);
}
fill("#477645");
stroke(255);
beginShape();
vertex(-5, height);
vertex(-5, height - getHeight(0));
for(let i = 0; i < heights.length; i ++) {
vertex(i * w, height-getHeight(i));
}
vertex(width + 5, height - getHeight(heights.length - 1));
vertex(width + 5, height);
endShape();
const rayX1 = width * 3/4;
const rayX2 = width/3 + 20;
const rY = height/3;
const t1y = min()
const rX = lerp(rayX1, rayX2, tRay1);
const h = height - lerpHeight(rX);
const s = 0.7 * ((cos(tScale * TAU * 2) + 1) / 4 + 0.5);
const dy = (h - rY) * s;
stroke(255);
arrow(rX, rY, rX, lerp(rY, h, tV1), 10);
arrow(rX, rY, rX - dy * tH1, rY, 10);
noStroke();
fill("#D6B69E");
circle(rX, rY, 20);
}
function mipMap(arr) {
const mip = [];
for(let i = 0; i < arr.length; i += 2) {
mip.push(max(arr[i], arr[i + 1]));
}
return mip;
}
function arrow(x1, y1, x2, y2, arrowLength) {
const a = atan2(y2 - y1, x2 - x1);
const r = dist(x1, y1, x2, y2);
if(r < 3) {
return;
}
push();
translate(x1, y1);
rotate(a);
line(0, 0, r, 0);
translate(r, 0);
push();
rotate(PI/6);
line(0, 0, -arrowLength, 0);
pop();
rotate(-PI/6);
line(0, 0, -arrowLength, 0);
pop();
}