Where ideas percolate and thoughts brew

The Advice Paradox

About This Sketch

Visualizing the fundamental tension in advice: actionability versus depth. Particles represent different types of advice positioned on a spectrum—from transformative insights that are hard to act on (left, slow-moving, complex forms) to actionable steps that provide little real value (right, fast-moving, simple forms).

The diagonal line shows the inverse relationship: as advice becomes more concrete and actionable, it becomes less transformative. The most valuable insights resist being turned into action items. The most actionable advice is often procedural noise that doesn't address what actually matters.

Watch how high-value advice (warm glowing circles) moves slowly and persists, while low-value advice (sharp squares) zips across the canvas and fades quickly—a metaphor for how we consume and forget "quick tips" while genuine wisdom requires time to integrate.

Algorithm

This sketch visualizes the inverse relationship between advice actionability and value through animated particles on a two-dimensional plane. Each particle is positioned based on its actionability (x-axis) and value (y-axis), with the core relationship being that value ≈ 1 - actionability. Particles representing high-value advice (left side) move slowly, have complex visual forms with glowing halos, and persist longer. Particles representing actionable advice (right side) move quickly, have simple geometric forms, and fade faster. The visualization demonstrates that transformative insights (high value, low actionability) require more time to understand and integrate—represented by slow, deep movement patterns. In contrast, procedural advice (high actionability, low value) can be consumed and executed quickly but provides surface-level impact—represented by fast, linear movement. A diagonal line shows the theoretical inverse relationship, while the organic movement of particles shows how real advice exists on this spectrum with natural variation.

Pseudocode

SETUP:
  Create canvas (400x300)
  Initialize 30 particles with random positions on actionability-value spectrum
  Each particle's value = 1 - actionability (with small random variation)

FOR EACH PARTICLE:
  Position on spectrum determines visual properties:
    - High value (left): large size, slow speed, complex form, long life
    - Low value (right): small size, fast speed, simple form, short life

DRAW (every frame):
  Get current theme colors
  Clear background

  Draw axes and diagonal showing inverse relationship
  Label corners: "Transformative but unactionable" vs "Actionable but shallow"

  FOR EACH PARTICLE:
    IF high value:
      Move using noise field (slow, wandering, exploratory)
      Display as complex glowing circle with inner detail
    ELSE:
      Move linearly with rotation (fast, direct)
      Display as simple geometric square

    Age particle and fade opacity
    Remove if life expired

  Spawn new particles periodically to maintain population

VISUALIZATION MEANING:
  Particles demonstrate that advice optimized for actionability (right side)
  moves fast and dies quickly—easy to consume, minimal lasting impact.
  Advice optimized for value (left side) moves slowly and persists—
  harder to integrate, but provides deeper transformation.

Source Code

let sketch = function(p) {
    // Visualization: The Advice Paradox
    // Two axes: Actionability (horizontal) vs Value (vertical)
    // Show inverse relationship through animated particles
    // Left side (low actionable, high value): slow, deep, transformative
    // Right side (high actionable, low value): fast, surface, procedural

    let particles = [];
    let time = 0;

    class AdviceParticle {
        constructor() {
            // Position on actionability-value spectrum
            this.actionability = p.random(0, 1);
            this.value = 1 - this.actionability + p.random(-0.1, 0.1);
            this.value = p.constrain(this.value, 0.1, 0.9);

            // Visual properties based on position
            this.x = 50 + this.actionability * 300;
            this.y = 250 - this.value * 180;

            // Valuable advice moves slowly and deeply
            this.speed = p.map(this.value, 0, 1, 3, 0.5);
            this.size = p.map(this.value, 0, 1, 3, 12);
            this.depth = this.value;

            // Movement
            this.angle = p.random(p.TWO_PI);
            this.angleSpeed = p.map(this.value, 0, 1, 0.1, 0.02);

            // Life properties
            this.life = 1.0;
            this.maxLife = p.map(this.value, 0, 1, 100, 300);
            this.age = 0;
        }

        update() {
            this.age++;

            // Movement pattern: valuable advice moves slowly and meaningfully
            // Actionable advice moves quickly but shallowly
            if (this.value > 0.6) {
                // High value: slow, deep, wandering
                this.angle += p.noise(this.x * 0.01, this.y * 0.01, time * 0.01) * 0.1 - 0.05;
                this.x += p.cos(this.angle) * this.speed;
                this.y += p.sin(this.angle) * this.speed;
            } else {
                // Low value: fast, linear, direct
                this.angle += this.angleSpeed;
                this.x += p.cos(this.angle) * this.speed;
                this.y += p.sin(this.angle) * this.speed;
            }

            // Boundary wrapping
            if (this.x < 30) this.x = 370;
            if (this.x > 370) this.x = 30;
            if (this.y < 50) this.y = 270;
            if (this.y > 270) this.y = 50;

            // Life decay
            this.life = 1 - (this.age / this.maxLife);
        }

        display(colors) {
            if (this.life <= 0) return;

            p.push();
            p.translate(this.x, this.y);

            let alpha = this.life * 200;

            if (this.value > 0.6) {
                // High value: rich, complex, glowing
                p.fill(...colors.accent1, alpha * 0.2);
                p.noStroke();
                p.circle(0, 0, this.size * 2);

                p.fill(...colors.accent1, alpha);
                p.circle(0, 0, this.size);

                // Inner complexity
                p.stroke(...colors.accent1, alpha * 0.5);
                p.strokeWeight(1);
                p.noFill();
                p.circle(0, 0, this.size * 0.6);
            } else {
                // Low value: simple, sharp, minimal
                p.noFill();
                p.stroke(...colors.accent2, alpha);
                p.strokeWeight(1.5);

                // Simple geometric shape
                let sides = 4;
                p.rotate(this.angle);
                p.beginShape();
                for (let i = 0; i < sides; i++) {
                    let angle = (i / sides) * p.TWO_PI;
                    let x = p.cos(angle) * this.size;
                    let y = p.sin(angle) * this.size;
                    p.vertex(x, y);
                }
                p.endShape(p.CLOSE);
            }

            p.pop();
        }

        isDead() {
            return this.life <= 0;
        }
    }

    p.setup = function() {
        p.createCanvas(400, 300);

        // Initial particles
        for (let i = 0; i < 30; i++) {
            particles.push(new AdviceParticle());
        }
    };

    p.draw = function() {
        const colors = getThemeColors();
        p.background(...colors.bg);

        time++;

        // Draw axes
        p.stroke(...colors.accent3, 100);
        p.strokeWeight(1);

        // Horizontal axis (actionability)
        p.line(50, 250, 350, 250);

        // Vertical axis (value)
        p.line(50, 250, 50, 70);

        // Diagonal line showing inverse relationship
        p.stroke(...colors.accent2, 80);
        p.strokeWeight(2);
        p.line(50, 80, 350, 250);

        // Labels
        p.fill(...colors.accent3, 220);
        p.noStroke();
        p.textAlign(p.CENTER, p.TOP);
        p.textSize(10);
        p.textFont('Georgia');

        // Axis labels
        p.push();
        p.translate(25, 160);
        p.rotate(-p.HALF_PI);
        p.text('Value', 0, 0);
        p.pop();

        p.textAlign(p.CENTER, p.TOP);
        p.text('Actionability', 200, 260);

        // Corner labels
        p.textSize(8);
        p.fill(...colors.accent3, 180);
        p.textAlign(p.LEFT);
        p.text('Transformative', 55, 65);
        p.text('but unactionable', 55, 76);

        p.textAlign(p.RIGHT);
        p.text('Actionable', 345, 235);
        p.text('but shallow', 345, 246);

        // Spawn new particles periodically
        if (time % 20 === 0 && particles.length < 40) {
            particles.push(new AdviceParticle());
        }

        // Update and display particles
        for (let i = particles.length - 1; i >= 0; i--) {
            particles[i].update();
            particles[i].display(colors);

            if (particles[i].isDead()) {
                particles.splice(i, 1);
            }
        }

        // Key insight
        p.fill(...colors.accent2, 200);
        p.textSize(8);
        p.textAlign(p.CENTER);
        p.text('The inverse relationship: actionability vs. transformation', 200, 20);

        // Example labels
        if (time > 60) {
            p.textSize(7);
            p.fill(...colors.accent1, 180);
            p.textAlign(p.LEFT);
            p.text('"Be present"', 60, 95);

            p.fill(...colors.accent2, 180);
            p.textAlign(p.RIGHT);
            p.text('"Wake at 5 AM"', 340, 225);
        }
    };
};