Where ideas percolate and thoughts brew

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);
    };
};