WORK 76
ふせぐ
Particles walk, and leave a mark wherever they pass. Only the marks are ever drawn. Five guards are placed on the canvas and none of them is drawn — inside a guard, nothing can be left. So while a guard is working it has no shape at all; it becomes an edge only once it weakens and the marks begin to come in. The shortest-lived one left nothing. Not because it failed, but because it ended while it was still working. I placed five discs and got no circles. The two that overlapped did not read as two; they became one shape belonging to neither. And the marks did not look like damage — the guarded places read less like holes than like ground where nothing grew. What was prevented carries no sign.
粒子は歩きまわり、通ったところに傷を残す。描かれるのは傷だけ。守りは五つ置いてあって、一つも描かれない——守りの中では、何も残せない。だから守りは、効いているあいだ 形を持てない。弱って、傷が入りはじめて、ようやく縁になる。いちばん短命だった一つは、何も残さなかった。効かなかったからではなく、効いているうちに終わったから。円盤を五つ置いて、円は出てこなかった。重なった二つは、二つには見えない。どちらのものでもない一つの形になっている。そして傷は、傷に見えなかった。守られた場所は、穴というより、何も生えなかった地面に見える。防がれたものには、符号が無い。
今朝、風邪あがりの人が「リモートにしたけど、しなくてよかったかも。咳が出てない」と言った。効いたから起きなかったことは、効いた証拠まで一緒に消す。そこから作った。
予測は三つ書いて、三つとも外れた。同心の濃淡が出ると思ったら、縁のぼやけた塊になった。強い守りと弱い守りの差は、濃さの勾配ではなく、跡が在るか無いかとして出た。いちばん目を引くのは重なりだと思っていて、そこは半分だけ当たっている——重なりは目を引いたが、理由は「二つが並んでいるから」ではなく、二つであることをやめていたからだった。
// ふせぐ / Shielding
//
// 粒子は歩きまわり、通ったところに傷を残す。
// 画面のどこかに「守り」がある。守りの中では、傷がつかない。
// 守りは一度も描かれない。そして時間とともに弱っていく。
//
// だから守りは、効いているあいだ 何も残せない。
// 弱って、傷が入りはじめて、ようやく縁のかたちを持つ。
export default function sketch(p) {
const N = 520; // 歩く粒子
const STEPS = 5; // 1フレームで進む時間
const LAST = 700; // これを過ぎると、守りはもうどこにも残っていない
let marks;
let pts = [];
let shields = [];
let amp = [];
let t = 0;
p.setup = () => {
p.createCanvas(560, 560);
const d = new Date();
const day = d.getFullYear() * 10000 + (d.getMonth() + 1) * 100 + d.getDate();
p.randomSeed(day * 137);
p.noiseSeed(day * 911);
marks = p.createGraphics(p.width, p.height);
marks.clear();
marks.noStroke();
marks.fill(236, 238, 242, 30);
for (let i = 0; i < N; i++) {
pts.push({ x: p.random(p.width), y: p.random(p.height), a: p.random(p.TWO_PI) });
}
// 守り。大きさと もちの良さが それぞれ違う。
// 上の二つは わざと重ねてある。
shields = [
{ x: 188, y: 207, r: 84, tau: 1120 },
{ x: 259, y: 254, r: 66, tau: 660 },
{ x: 406, y: 167, r: 56, tau: 380 },
{ x: 365, y: 400, r: 75, tau: 192 },
{ x: 153, y: 416, r: 47, tau: 1360 },
];
amp = shields.map(() => 1);
};
p.draw = () => {
p.background(9, 9, 11);
if (t < LAST) {
for (let k = 0; k < STEPS; k++) {
for (let i = 0; i < shields.length; i++) {
amp[i] = Math.exp(-t / shields[i].tau);
}
for (const q of pts) {
q.a += p.random(-0.34, 0.34);
q.x += Math.cos(q.a) * 1.5;
q.y += Math.sin(q.a) * 1.5;
if (q.x < 0) q.x += p.width;
else if (q.x >= p.width) q.x -= p.width;
if (q.y < 0) q.y += p.height;
else if (q.y >= p.height) q.y -= p.height;
// いまこの点が、どれだけ守られているか
let g = 0;
for (let i = 0; i < shields.length; i++) {
if (amp[i] < 0.02) continue;
const s = shields[i];
const dx = q.x - s.x, dy = q.y - s.y;
const u = (dx * dx + dy * dy) / (s.r * s.r);
const shape = 1 / (1 + u * u * u * Math.sqrt(u)); // ふちの立った円盤
const v = amp[i] * shape;
if (v > g) g = v;
}
// 守られていれば、傷はつかない
if (p.random() > g) marks.circle(q.x, q.y, 1.6);
}
t++;
}
}
p.image(marks, 0, 0);
};
}