The Right Decision Myth
About This Sketch
Visualizing the right decision myth Left: Multiple decision paths being analyzed endlessly (stuck at crossroads) Right: One path chosen with full commitment showing growth/progress Shows contrast between decision paralysis vs. committed execution
This sketch accompanies the blog post "The Right Decision Myth" and visualizes its core concepts through generative art.
Algorithm
Visualizing the right decision myth Left: Multiple decision paths being analyzed endlessly (stuck at crossroads) Right: One path chosen with full commitment showing growth/progress Shows contrast between decision paralysis vs. committed execution
This sketch was originally created as a visual companion to the blog post "The Right Decision Myth" and explores its themes through generative art.
Pseudocode
SETUP:
Initialize canvas (400x300)
Set up drawing parameters
DRAW (every frame):
Get current theme colors
Clear background
Draw generative visualization
Update animation state
Source Code
let sketch = function(p) {
// Visualizing the right decision myth
// Left: Multiple decision paths being analyzed endlessly (stuck at crossroads)
// Right: One path chosen with full commitment showing growth/progress
// Shows contrast between decision paralysis vs. committed execution
let time = 0;
let decisionPaths = [];
let committedPath = null;
let analysisParticles = [];
class DecisionPath {
constructor(x, y, angle, index) {
this.x = x;
this.y = y;
this.angle = angle;
this.length = 0;
this.maxLength = 60;
this.index = index;
this.weight = 2;
this.analyzing = true;
}
update() {
// Paths grow tentatively then retract - never committing
if (this.analyzing) {
let growth = p.sin(time * 0.02 + this.index * 0.5);
this.length = p.map(growth, -1, 1, 10, this.maxLength);
this.weight = p.map(growth, -1, 1, 1, 3);
}
}
display(colors) {
p.push();
p.translate(this.x, this.y);
p.rotate(this.angle);
// Tentative, wavering line
p.stroke(...colors.accent3, 140);
p.strokeWeight(this.weight);
p.noFill();
p.beginShape();
for (let i = 0; i <= this.length; i += 3) {
// Wavy, uncertain path
let yOffset = p.sin(i * 0.1 + time * 0.05) * 2;
p.vertex(i, yOffset);
}
p.endShape();
// Question marks at the end
if (time % 90 > 45) {
let qAlpha = p.map(time % 45, 0, 45, 0, 180);
p.noStroke();
p.fill(...colors.accent3, qAlpha);
p.textAlign(p.CENTER, p.CENTER);
p.textSize(10);
p.text("?", this.length, 0);
}
p.pop();
}
}
class CommittedPath {
constructor(x, y) {
this.x = x;
this.y = y;
this.length = 0;
this.maxLength = 120;
this.width = 6;
this.growing = true;
this.milestones = [];
this.growth = 0;
}
update() {
// Steady, consistent growth
if (this.growing && this.length < this.maxLength) {
this.length += 0.5;
this.growth += 0.5;
// Add milestones periodically
if (this.length > 20 && this.length % 25 < 0.5) {
this.milestones.push({
pos: this.length,
time: time,
size: 0
});
}
}
// Update milestones
for (let m of this.milestones) {
if (m.size < 10) m.size += 0.3;
}
}
display(colors) {
p.push();
p.translate(this.x, this.y);
// Strong, committed line going forward
p.stroke(...colors.accent1, 200);
p.strokeWeight(this.width);
p.noFill();
// Main path
p.beginShape();
for (let i = 0; i <= this.length; i += 2) {
// Mostly straight with slight natural variation
let yOffset = p.sin(i * 0.05) * 1;
p.vertex(i, yOffset);
}
p.endShape();
// Growth glow at the tip
if (this.length < this.maxLength) {
p.noStroke();
for (let r = 20; r > 0; r -= 4) {
let alpha = p.map(r, 0, 20, 0, 80);
p.fill(...colors.accent1, alpha);
p.circle(this.length, 0, r);
}
}
// Milestones - achievements along the way
for (let m of this.milestones) {
p.noStroke();
p.fill(...colors.accent2, 180);
p.circle(m.pos, 0, m.size);
// Checkmark inside
if (m.size > 8) {
p.stroke(...colors.bg, 200);
p.strokeWeight(1.5);
p.noFill();
p.beginShape();
let cx = m.pos;
p.vertex(cx - 3, 0);
p.vertex(cx - 1, 2);
p.vertex(cx + 3, -3);
p.endShape();
}
}
p.pop();
}
}
class AnalysisParticle {
constructor(x, y) {
this.x = x;
this.y = y;
this.vx = p.random(-0.5, 0.5);
this.vy = p.random(-0.5, 0.5);
this.life = 255;
this.size = p.random(2, 4);
}
update() {
this.x += this.vx;
this.y += this.vy;
this.life -= 2;
// Circular motion - going in circles
this.vx += p.random(-0.1, 0.1);
this.vy += p.random(-0.1, 0.1);
// Keep near center
let dx = 80 - this.x;
let dy = 150 - this.y;
this.vx += dx * 0.001;
this.vy += dy * 0.001;
}
display(colors) {
p.noStroke();
p.fill(...colors.accent3, this.life * 0.6);
p.circle(this.x, this.y, this.size);
}
isDead() {
return this.life <= 0;
}
}
p.setup = function() {
p.createCanvas(400, 300);
p.colorMode(p.RGB);
// Create multiple decision paths radiating from center (left side)
let centerX = 80;
let centerY = 150;
for (let i = 0; i < 6; i++) {
let angle = p.map(i, 0, 6, -p.PI * 0.6, p.PI * 0.6);
decisionPaths.push(new DecisionPath(centerX, centerY, angle, i));
}
// Committed path (right side) - starts later
committedPath = new CommittedPath(240, 150);
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
// Title
p.noStroke();
p.fill(...colors.accent3, 180);
p.textAlign(p.CENTER, p.TOP);
p.textSize(11);
p.text("The Right Decision Myth", 200, 15);
// Section labels
p.textSize(8);
p.fill(...colors.accent3, 160);
p.textAlign(p.CENTER, p.TOP);
p.text("Analyzing options", 80, 35);
p.text("Committing to one", 300, 35);
// Dividing line
p.stroke(...colors.accent3, 60);
p.strokeWeight(1);
p.line(200, 60, 200, 240);
// Left side: Decision paralysis
// Add analysis particles
if (p.random() < 0.3) {
analysisParticles.push(new AnalysisParticle(
80 + p.random(-20, 20),
150 + p.random(-20, 20)
));
}
// Update and display particles
for (let i = analysisParticles.length - 1; i >= 0; i--) {
analysisParticles[i].update();
analysisParticles[i].display(colors);
if (analysisParticles[i].isDead()) {
analysisParticles.splice(i, 1);
}
}
// Display decision paths - wavering, uncertain
for (let path of decisionPaths) {
path.update();
path.display(colors);
}
// Center point - stuck at crossroads
p.noStroke();
p.fill(...colors.accent3, 160);
p.circle(80, 150, 8);
// Right side: Committed path
if (time > 60) {
committedPath.update();
committedPath.display(colors);
// Starting point
p.noStroke();
p.fill(...colors.accent1, 180);
p.circle(240, 150, 8);
}
// Labels and comparisons
if (time > 120) {
let labelAlpha = Math.min((time - 120) * 2, 160);
p.textAlign(p.CENTER, p.TOP);
p.textSize(7);
p.noStroke();
p.fill(...colors.accent3, labelAlpha);
p.text("\"Which path is right?\"", 80, 210);
p.text("6 months analyzing", 80, 222);
if (time > 180) {
p.fill(...colors.accent1, labelAlpha);
p.text("\"This one. Let's go.\"", 300, 210);
p.text("6 months building", 300, 222);
}
}
// Show progress comparison
if (time > 300) {
let compAlpha = Math.min((time - 300) * 1.5, 180);
p.textAlign(p.CENTER, p.BOTTOM);
p.textSize(8);
p.fill(...colors.accent3, compAlpha);
p.text("Progress: None", 80, 270);
p.fill(...colors.accent1, compAlpha);
let progress = Math.floor(committedPath.growth / 2);
p.text(`Progress: ${progress}`, 300, 270);
}
// Core insight
if (time > 420) {
let insightAlpha = Math.min((time - 420) * 2, 170);
p.textAlign(p.CENTER, p.BOTTOM);
p.textSize(8);
p.fill(...colors.accent2, insightAlpha);
p.text("The commitment matters more than the choice", 200, 290);
}
// Show the trap
if (time > 240 && time < 360) {
let trapAlpha = p.map(p.sin((time - 240) / 40), -1, 1, 100, 180);
// "WHICH?" over decision paths
p.push();
p.textAlign(p.CENTER, p.CENTER);
p.textSize(14);
p.fill(...colors.accent3, trapAlpha);
p.text("WHICH?", 80, 90);
p.pop();
// Arrow showing movement on committed side
p.push();
p.stroke(...colors.accent1, trapAlpha);
p.strokeWeight(2);
p.fill(...colors.accent1, trapAlpha);
let arrowX = 260 + committedPath.length * 0.3;
p.line(arrowX - 10, 180, arrowX, 180);
p.triangle(arrowX, 180, arrowX - 6, 177, arrowX - 6, 183);
p.pop();
}
// Satisfaction comparison over time
if (time > 540) {
let satAlpha = Math.min((time - 540) * 2, 150);
p.push();
p.textAlign(p.LEFT, p.TOP);
p.textSize(7);
p.noStroke();
// Left side - anxiety
p.fill(...colors.accent3, satAlpha);
p.text("Anxiety: ↑↑↑", 25, 250);
p.text("Results: →", 25, 262);
// Right side - progress
p.fill(...colors.accent1, satAlpha);
p.text("Clarity: ↑", 230, 250);
p.text("Results: ↑↑", 230, 262);
p.pop();
}
time++;
// Loop
if (time > 720) {
time = 0;
// Reset committed path to show cycle again
committedPath = new CommittedPath(240, 150);
}
};
};