Mimetic vs. Intrinsic Desire
About This Sketch
Two particle systems visualize RenΓ© Girard's mimetic desire against Self-Determination Theory's intrinsic motivation. On the left, particles frantically chase a shared desirability signal that keeps moving β reactive, noisy, never settled. On the right, each particle follows its own fixed attractor β independent, steady, purposeful. Same energy, different architecture.
Algorithm
Two particle systems side by side, separated by a dividing line.
Left (mimetic desire): particles chase a shared pulsing attractor that
periodically relocates. A Perlin noise field adds jitter, keeping movement
reactive and unsettled.
Right (intrinsic desire): each particle has its own fixed private attractor.
Particles move steadily toward their unique point and orbit it calmly.
Pseudocode
SETUP:
Create 18 mimetic particles scattered on left half
Create 10 intrinsic particles on right half, each with unique attractor
Randomize initial mimetic target position
DRAW:
Draw dividing line
LEFT SIDE (mimetic):
Decrement target timer; relocate target when timer expires
Draw pulsing glow around shared target
For each particle:
Compute attraction force toward shared target
Add Perlin noise jitter
Apply damping, update position
Constrain to left half
RIGHT SIDE (intrinsic):
For each particle:
Draw faint ring and dot at its private attractor
Compute steady pull toward own attractor
Apply damping, update position
Constrain to right half
Draw labels
Source Code
let sketch = function(p) {
const W = 400, H = 300;
const MID = W / 2;
let mParticles = [];
let mTarget = { x: 0, y: 0 };
let mTargetTimer = 0;
const M_COUNT = 18;
let iParticles = [];
const I_COUNT = 10;
function moveMimeticTarget() {
mTarget.x = p.random(40, MID - 40);
mTarget.y = p.random(50, H - 50);
mTargetTimer = p.floor(p.random(100, 160));
}
function resetMimetic() {
mParticles = [];
for (let i = 0; i < M_COUNT; i++) {
mParticles.push({
x: p.random(18, MID - 14),
y: p.random(30, H - 30),
vx: p.random(-0.5, 0.5),
vy: p.random(-0.5, 0.5),
size: p.random(3.5, 6)
});
}
moveMimeticTarget();
}
function resetIntrinsic() {
iParticles = [];
for (let i = 0; i < I_COUNT; i++) {
iParticles.push({
x: p.random(MID + 14, W - 18),
y: p.random(30, H - 30),
vx: p.random(-0.4, 0.4),
vy: p.random(-0.4, 0.4),
ax: p.random(MID + 30, W - 30),
ay: p.random(40, H - 40),
size: p.random(4, 6.5)
});
}
}
p.setup = function() {
p.createCanvas(W, H);
p.colorMode(p.RGB);
resetMimetic();
resetIntrinsic();
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
let t = p.frameCount * 0.012;
p.stroke(colors.accent3[0], colors.accent3[1], colors.accent3[2], 45);
p.strokeWeight(1);
p.line(MID, 18, MID, H - 18);
mTargetTimer--;
if (mTargetTimer <= 0) moveMimeticTarget();
let pulse = 0.5 + 0.5 * Math.sin(t * 2.5);
for (let r = 32; r > 4; r -= 7) {
p.noStroke();
p.fill(colors.accent2[0], colors.accent2[1], colors.accent2[2],
p.map(r, 4, 32, 0, 18 + pulse * 14));
p.ellipse(mTarget.x, mTarget.y, r * 2, r * 2);
}
p.fill(...colors.accent2, 180 + pulse * 60);
p.noStroke();
p.ellipse(mTarget.x, mTarget.y, 7 + pulse * 3, 7 + pulse * 3);
for (let mp of mParticles) {
let dx = mTarget.x - mp.x;
let dy = mTarget.y - mp.y;
let dist = Math.sqrt(dx * dx + dy * dy);
let force = 0.18 / Math.max(dist, 12);
mp.vx += dx * force;
mp.vy += dy * force;
mp.vx += p.noise(mp.x * 0.03, mp.y * 0.03, t * 0.4) * 0.3 - 0.15;
mp.vy += p.noise(mp.x * 0.03 + 50, mp.y * 0.03, t * 0.4) * 0.3 - 0.15;
mp.vx *= 0.88;
mp.vy *= 0.88;
mp.x += mp.vx;
mp.y += mp.vy;
mp.x = p.constrain(mp.x, 10, MID - 10);
mp.y = p.constrain(mp.y, 14, H - 14);
p.fill(colors.accent2[0], colors.accent2[1], colors.accent2[2], 160);
p.noStroke();
p.ellipse(mp.x, mp.y, mp.size, mp.size);
}
p.noStroke();
p.fill(colors.accent3[0], colors.accent3[1], colors.accent3[2], 100);
p.textAlign(p.CENTER);
p.textSize(8.5);
p.text("mimetic desire", MID / 2, H - 10);
for (let ip of iParticles) {
p.noFill();
p.stroke(colors.accent1[0], colors.accent1[1], colors.accent1[2], 30);
p.strokeWeight(1);
p.ellipse(ip.ax, ip.ay, 20, 20);
p.fill(...colors.accent1, 120);
p.noStroke();
p.ellipse(ip.ax, ip.ay, 5, 5);
}
for (let ip of iParticles) {
let dx = ip.ax - ip.x;
let dy = ip.ay - ip.y;
let dist = Math.sqrt(dx * dx + dy * dy);
let force = 0.12 / Math.max(dist, 10);
ip.vx += dx * force;
ip.vy += dy * force;
ip.vx *= 0.90;
ip.vy *= 0.90;
ip.x += ip.vx;
ip.y += ip.vy;
ip.x = p.constrain(ip.x, MID + 10, W - 10);
ip.y = p.constrain(ip.y, 14, H - 14);
p.fill(colors.accent1[0], colors.accent1[1], colors.accent1[2], 190);
p.noStroke();
p.ellipse(ip.x, ip.y, ip.size, ip.size);
}
p.noStroke();
p.fill(colors.accent3[0], colors.accent3[1], colors.accent3[2], 100);
p.textAlign(p.CENTER);
p.textSize(8.5);
p.text("intrinsic desire", MID + (W - MID) / 2, H - 10);
};
};