Advice Is Autobiography
About This Sketch
Two orbital systems separated by a dashed line. Warm-colored advice particles fire from the left (advisor's world) and land on the right (your world) — but they arrive at positions shaped by the left's structure, not the right's. They drift and fade because the topology doesn't match. A visualization of why advice that worked for someone else rarely transfers cleanly.
Algorithm
Two orbital systems — left (advisor's world, 3 orbiters at radii 30/52/72) and right (your world, 2 orbiters at radii 22/58). Every ~85 frames, a warm-colored advice particle fires from a left orbiter toward the right side, landing at the *left's* orbital radius from the right center. Since those radii don't match the right system's structure, the particle doesn't integrate — it drifts and fades. The visual mismatch shows the core idea: advice is shaped by the advisor's topology, not yours.
Pseudocode
SETUP:
Create left orbital system (3 orbiters, radii 30/52/72)
Create right orbital system (2 orbiters, radii 22/58)
DRAW:
Update all orbiter angles and positions
Draw dashed divider at x=200
Label each half: "advisor's world" / "your world"
Draw subtle orbit rings for each system
Draw center dots and orbiter dots (warm left, muted right)
Every 85 frames:
Pick random left orbiter as source
Fire advice particle toward right center at source's radius
For each in-flight particle:
Move toward target
Draw particle + short trail
On arrival: convert to landed state
For each landed particle:
Drift slowly with friction
Fade out over time
Remove when invisible
Source Code
let leftOrbiters = [];
let rightOrbiters = [];
let adviceParticles = [];
let landedAdvice = [];
let timer = 0;
let sketch = function(p) {
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
let lCfg = [
{radius: 30, speed: 0.025, angle: 0},
{radius: 52, speed: 0.015, angle: 2.1},
{radius: 72, speed: 0.009, angle: 4.3}
];
for (let c of lCfg) {
leftOrbiters.push({cx: 100, cy: 150, radius: c.radius, speed: c.speed, angle: c.angle, x: 0, y: 0});
}
let rCfg = [
{radius: 22, speed: 0.020, angle: 1.0},
{radius: 58, speed: 0.007, angle: 3.5}
];
for (let c of rCfg) {
rightOrbiters.push({cx: 300, cy: 150, radius: c.radius, speed: c.speed, angle: c.angle, x: 0, y: 0});
}
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
timer++;
for (let o of leftOrbiters) {
o.angle += o.speed;
o.x = o.cx + p.cos(o.angle) * o.radius;
o.y = o.cy + p.sin(o.angle) * o.radius;
}
for (let o of rightOrbiters) {
o.angle += o.speed;
o.x = o.cx + p.cos(o.angle) * o.radius;
o.y = o.cy + p.sin(o.angle) * o.radius;
}
p.stroke(...colors.accent3, 50);
p.strokeWeight(1);
for (let y = 30; y < 275; y += 10) {
p.line(200, y, 200, y + 5);
}
p.noStroke();
p.fill(...colors.accent3, 160);
p.textSize(9);
p.textAlign(p.CENTER);
p.text("advisor's world", 100, 22);
p.text("your world", 300, 22);
p.noFill();
for (let o of leftOrbiters) {
p.stroke(...colors.accent1, 28);
p.strokeWeight(1);
p.ellipse(o.cx, o.cy, o.radius * 2, o.radius * 2);
}
for (let o of rightOrbiters) {
p.stroke(...colors.accent3, 28);
p.strokeWeight(1);
p.ellipse(o.cx, o.cy, o.radius * 2, o.radius * 2);
}
p.noStroke();
p.fill(...colors.accent2);
p.ellipse(100, 150, 10, 10);
p.fill(...colors.accent3);
p.ellipse(300, 150, 10, 10);
p.fill(...colors.accent2);
for (let o of leftOrbiters) {
p.ellipse(o.x, o.y, 7, 7);
}
p.fill(...colors.accent3);
for (let o of rightOrbiters) {
p.ellipse(o.x, o.y, 7, 7);
}
if (timer % 85 === 0 && leftOrbiters.length > 0) {
let src = leftOrbiters[Math.floor(p.random(leftOrbiters.length))];
let landAngle = p.random(p.TWO_PI);
adviceParticles.push({
x: src.x, y: src.y,
tx: 300 + p.cos(landAngle) * src.radius,
ty: 150 + p.sin(landAngle) * src.radius,
speed: 1.8
});
}
for (let i = adviceParticles.length - 1; i >= 0; i--) {
let ap = adviceParticles[i];
let dx = ap.tx - ap.x;
let dy = ap.ty - ap.y;
let d = p.sqrt(dx * dx + dy * dy);
if (d > 2) {
ap.x += (dx / d) * ap.speed;
ap.y += (dy / d) * ap.speed;
p.noStroke();
p.fill(...colors.accent2, 200);
p.ellipse(ap.x, ap.y, 5, 5);
p.fill(...colors.accent2, 80);
p.ellipse(ap.x - (dx / d) * 7, ap.y - (dy / d) * 7, 3, 3);
} else {
landedAdvice.push({
x: ap.tx, y: ap.ty,
vx: p.random(-0.3, 0.3),
vy: p.random(-0.2, 0.2),
life: 1.0
});
adviceParticles.splice(i, 1);
}
}
for (let i = landedAdvice.length - 1; i >= 0; i--) {
let la = landedAdvice[i];
la.x += la.vx;
la.y += la.vy;
la.vx *= 0.99;
la.vy *= 0.99;
la.life -= 0.006;
p.noStroke();
p.fill(...colors.accent2, la.life * 170);
p.ellipse(la.x, la.y, 5, 5);
if (la.life <= 0) landedAdvice.splice(i, 1);
}
p.noStroke();
p.fill(...colors.accent2, 200);
p.ellipse(18, p.height - 20, 6, 6);
p.fill(...colors.accent3, 160);
p.textSize(8);
p.textAlign(p.LEFT);
p.text("advice crossing worlds", 28, p.height - 16);
};
};